воскресенье, сентября 17, 2006

По итогам вчерашних полночных бдений за связкой FarEditor-csc

1) Функции высшего порядка и ленивые списки (в т.ч. реализованные через итераторы .NET) рулят;
2) Использование вышеперечисленного и generic-ов вообще в языке, не поддерживающем type-inference - акт мазохизма;
3) отсутствие механизма макросов в Шарпе начинает напрягать... избаловался, блин!

Юзаю Nemerle и жду третьего шарпа. Хотя зачем?

воскресенье, августа 27, 2006

Продолжая тему языков ;)

Изучаю внутренности такого замечательного языка, как Mondrian.

Краткая характерстика:

- "чистый" (без побочных эффектов) функциональный язык;

- по синтаксису - смесь урезанного Haskell'а с Java;

- как и Хаскелл, реализует очень своеобразный ООП;

- компилится под .NET 1.1 (под 2.0, ес-сно, тоже);

- предполагаемая ниша - ASP.NET-программирование;



Также в пакет входит и компилятор для Haskell под .NET (для работы требуется наличие компилятора GHC, точнее, видимо, его либ), правда, скорее препроцессор Haskell->Mondrian.

Впрочем, сам компилятор Mondrian порождает код на C#, так что компиляция с Haskell представляет собой компиляцию Haskell->Mondrian->C#->.NET. Что само по себе забавно :)



Впрочем, это еще детский сад.

Дело в том, что, насколько мой рассудок смог определить, программа на Mondrian выполняется в собственной виртуальной машине(!), реализованной в .NET(!!!).

По кр.м. программка HelloWorld трансформировалась в 50 шарповых строк, программка с двумя версиями вычисления факториала (рекурсивной и оконечно-рекурсивной) - в 300 с лишним (что утешает, т.к. заметно, что объем генерируемого кода растет нелинейно ;)).

Самый шок наступил, когда я заглянул в их ран-тайм библиотечку (исходники качать было в лом, посему заюзал мегаинструмент Reflector, декомпилирующий .NET-код в CIL, C#, VB, Delphi, MC++ и Chrome).

Так вот, эти извращенцы мало того, что наваяли свою ВМ, так они еще и написали, скажем, своb класс ы Vector, Stack и т.п. (что назыается, для внутреннего пользования), причем всякие разные перечисления элементов они смело реализовали сами, отлично от подхода, реализуемого в .NET, так как видимо, решили, что при переборе содержимого коллекции гораздо лучше написать

while (enumerator.hasMoreElements())

{

doStuffOn(enumerator.nextElement());

}

нежели

foreach(object in collection)

{

doStuffOn(object);

}

притом, что при нормальной реализации доступны будут оба варианта.

Ну и по мелочам: разницы между Int32 и Int64 компилятор видит с трудом (если видит), большое количество ошибок оставляет на откуп компилятору Шарпа.



Но есть и плюсы:

1) компилятор шустр (шустрее, чем, скажем, Nemerle; впрочем, учитывая интеллектуальность последнего, сравнивать некорректно)

2) синтаксис в чем-то привычнее, чем у Haskell'а;

и 3) проект закрыт!!!!!! Вот это не может не радовать!

на этой оптимистической ноте автор откланивается, предчувствуя, каким невыспанным он будет с утра.

Adieu!

 

четверг, августа 17, 2006

А я молодец!..

Наваял-таки мегакласс, который отбирает из компонентов лежащих на форме только имеющие нужный тип и позволяет выбрать из них нужный для установки property в другом компоненте/контроле.



Причем, после написания проверил, нет ли чего-то такого уже готового ;) во фреймворке. Как ни странно, нет! Даже велосипеда не получилось :)



Теперь устанавливать связи между компонентами можно в режиме визуальной разработки. Приятно!

Причем для подключения мегадевайсины надо всего лишь установить атрибут. Правда, достаточно корявый, так что тут есть над чем работать.

 

четверг, июля 13, 2006

Загадки дизайна .NET Base Class Library

В целом архитектура .NET мне нравится. Но есть некоторые загадки, в частности, в BCL...

Простой пример: пытаюсь (в N-ый раз) построить что-то вроде конвейера, чтобы можно было параллельно обрабатывать поток изображений.

Ну и мне влом описывать классы для этих самых наборов промежуточных результатов. А так как я последнее время загоняюсь по ФП, сразу захотелось поюзать кортежи, ведь это стандартная фича всех ФЯП. Однако пишется проект на Шарпе, а не на Nemerle ;), соответственно, встроенной поддержки кортежей нет :( Стал искать нечто подобное в библиотеке .NET.



Не поверите, но нашел. Но отнюдь не в System.Collections.Generic, не в System.Collections и не в System.Collections.Specialized.



Знаете, где?

В System.Web.UI! %)



Причем, увы, использование требует явного приведения типов (ибо хранятся там System.Object'ы), и имеются в наличии только пары (Pair) и триплеты (Triplet). Чего мне, в принципе, могло бы и хватить, но добавлять ссылки на System.Web меня не радует, так что лучше напишу сам ;)

 

вторник, мая 23, 2006

Третий путь ведет к просветлению...

Ага, я порадовался, конечно, что надыбал набор COM-объектов (и документацию достал!), котороые очень удобно использовать в .NET, достаточно только поутюжить dll-ку tlbimp-ом.

Только вот маленькая незадача: TlbImp не всегда корректно распознает типы. Т.е., если в COM-овской библиотеке типов был в качестве параметра unsigned char* (т.е., как правило, С-шный массив), то наивная утилита его представит как ref byte, а не как byte[]. Что, в общем-то, логично. Информацию о том, что сие есть, ей взять неоткуда. Или, скажем, вместо всенародно любимого винапишного HANDLE (который суть void* и которому в .NET соответстует IntPtr) везде оказался int.

Проблема №2: как известно, все COM-объекты реализуют интерфейс IUnknown. А посему стандартной является ситуация, при которой во все методы передается как раз IUnknown, а там представляемый им объект проверяется на прочие интерфейсы. Я вот лично считаю, что сие в общем случае есть антипаттерн. Ибо: 1) ликвидирует остатки типобезопасности; 2) код ни хрена не самодокументируемый (блин, я вот догадался, что IUnknown* pDibImage - это IDibImage pDibImage; а вот tlbimp - нет); 3) снижает расширяемость кода.

Но вернемся к нашим баранамобъектам. Как уж сказано, TlbImp не одарен ИИ (что вы хотите от утилиты весом 56K?) и венгерскую нотацию читать не умеет (я вот тоже не силен). Посему он тупо поставил в соответствие всем IUnknown* по Object'у и немедленно выпил сказал, что преобразование закончено. Меня эта ситуация не устроила, бо я уже воевал с подобными обертками и больше как-то не хочется.

Короче, задача звучит так: прикрутить либы к программе.

Варианты: 1) использовать "как есть". Отметен, как отстойный. Во-первых, придется постоянно делать приведение типов от Object к реальным типам объектов. А это суть кака. Во-вторых, если все методы, работающие, скажем, с хендлом окна будут требовать int, то я задолбаюсь писать MyWin.Handle.ToInt32(). И, что самое существенное, мне не хочется даже думать о том, как передать byte[] вместо ref byte. Скорее всего, это требует грязных извратов.

2) Написать обертку самому. Десяток классов (методов по 20), плюс реализуемые ими интерфейсы, которые, кажись, тоже придется описывать... Извиняйте, ломает.

3) Путь воина. ОтILDASMить сборку, поправить нужные места, сассемблировать ILASM'ом. Вот оно!!! Править нужно далеко не все, причем, в связи с регулярной структурой сборки, можно все это автоматизировать.

Попробовал. Понравилось. Особенно грело душу, когда после компиляции тестовая прога продолжала работать правильно. А ObjectBrowser в Студии показывал результаты моих трудов =)

Восторг - непередаваемый! Видно, что не совсем ишо тупой. Мелочь, а приятно...

Теперь осталось сочинить прожку, которая будет делать такую конверсию автоматически, на основании имен в венгерской записи. Должна же быть от этого израта хоть какая-то польза!! Главное - не забить ;)

З.Ы.: Все-таки я не хакер. Меня не заставишь лезть куда-то на нижний уровень, пока не припрет производственная необходимость. :)))

 

воскресенье, мая 21, 2006

В Шаолинь, животное!!!!

Я вот не знаю занятия, более воспитывающего силу воли и помогающего осознать глубинную сущность программирования, чем reverse-engineering.

Берем библиотечку объемом ~30-40 метров. Загружаем IDA. Медитируем...

До полного просветления/схождения с ума (обычно это равноценные понятия)

 

суббота, мая 20, 2006

Учите матчасть, бойцы!..

Блин, месяца два мы воевали, завертывая одну библиотечку (вернее, набор оных) до вида, более-менее удобного для использования (и просто удобного, и приемлемого в .NET-е). Ухху...

Сегодня попробовал обработать ее tlbimp-ом, о котором совсем недавно прочел (кто не знает - это утилитка из .NET SDK, которая по библиотеке типов COM создает сборку .NET). Обработал. Посмотрел ей внутре. Возматерился.

Ибо половину работы это с нас бы сняло. Там почти все (как я и предполагал) оформлено COM-объектами. Которые вполне приживаются в .NET.

Единственный минус - что эти объекты документированы еще хуже чем в скрывающей их библиотеке. Ибо в документации к той хотя бы по 4 строчки к каждой функции (из сотни) написано. А к объектам - вообще ничего.



Но все равно - инструментарий надо знать!!!

 

пятница, апреля 28, 2006

1961 - I "barely saw" the idea several times ca. 1961... The first was on the Burroughs 220 in the form of a style for transporting files from one Air Training Command installation to another. There were no standard operating systems or file formats back then, so some (t this day unknown) designer decided to finesse the problem by taking each file and dividing it into three parts. The third part was all of the actual data records of arbitrary size and format. The second part contained the B220 procedures that knew how to get at records and fields to copy and update the third part. And the first part was an array or relative pointers into entry points of the procedures in the second part (the initial pointers were in a standard order representing standard meanings).


К слову сказать, файлы тогда на перфолентах были... В лучшем случае...



1966 - The title was "Sketchpad: A man-machine graphical communication system" [Sutherland, 1963]. What it could do was quite remarkable, and completely foreign to any use of a computer I had ever encountered. The three big ideas that were easiest to grapple with were: it was the invention of modern interactive computer graphics; things were described by making a "master drawing" that could produce "instance drawings"; control and dynamics were supplied by "constraints," also in graphical form, that could be applied to the masters to shape an inter-related parts. Its data structures were hard to understand--the only vaguely familiar construct was the embedding of pointers to procedures and using a process called reverse indexing to jump through them to routines, like the 22- file system [Ross, 1961]. It was the first to have clipping and zooming windows...

так, вот уже и окошки показались...

Soon Dan had bootstrapped Smalltalk across , and for many months it was the sole software sytem to run on the Interim dynabook. Appendix I has an "acknowledgements" dodcument I wrote from this time that is interesting it its allocation of credits and the various priorities associated with them. My $230K was enough to get 15 of the original projected 30 machines (over the years some 2000 Interim Dynabooks were actually built. True to Schopenhauer's observation, Executive "X" now decided that the Interim Dynabook was a good idea and he wanted all but two for his lab (I was in the other lab). I had to go to considerable lengths to get our machines back, but finally succeeded.

Создание машин специально для ОО-систем...

И просто золотые слова:

Another way to think of all this is: though the late-binding of automatic storage allocations doesn't do anything a programmer can't do, its presence leads both to simpler and more powerful code. OOP is a late binding strategy for many things and all of them together hold off fragility and size explosion much longer than the older methodologies. In other words, human programmers aren't Turing machines--and the lesss their programming systems require Turing machine techniques the better.




Взято из "Early History of SmallTalk".

 

четверг, апреля 06, 2006

И эти люди запрещают мне ковыряться в носу!..

Я хре фигею с того, чем занимается Microsoft Research!

Им мало F# (клона OCaml под .NET), им мало С-omega (C# с элементами SQL; он, правда, как отдельный продукт не выйдет). У них есть еще и Vault.

Вкратце - это почти С (т.е. императивный "curly brackets" язык), но:

- со строгой типизацией;

- с модульностью;

- с generic функциями (например, передача параметра по ссылке реализуется именно с их помощью);

- с многочисленными реверансами в сторону ФП, как-то произвольное место объявления функций, передача их как параметры, кложуры, currying (!) и т.п.

- с непривычными для императивных языков типами, вроде кортежей (tuple) и вариантов (замена для enum'ов и union'ов), тоже явно перекочевавшими из Haskell и ML;

- с pattern-matching'ом (правда, только для switch'ей) оттуда же;

- с дополнительными атрибутами для типов (сам плохо понял и нервно курю, но похоже, что-то вроде DesignByContract на этапе компиляции - например для контроля того, что файл был открыт перед обращением 8-/);



Ужос!!! Если бы сюда еще и ООП, я бы возлюбил это всем сердцем (может быть)... Но где стал бы на этом писать - не знаю..