codegen?

12/3/08 13:52
singalen: (Default)
[personal profile] singalen
Мне стыдно у вас такое спрашивать... но я всё равно спрошу.

Зачем нужна кодогенерация?
Разве это не автоматизированный копи-пейст?
Ну, исключая случаи, выходящие за пределы возможностей инструмента: там, сериализация в C++ или сгенерировать Data Object по XML-ю.

И просьбочка: если видите что-то полезное в моём аглицком блоге про .NET, немного Java, WiX, OOP, OOD и немного всё остальное - поставьте на него ссылку, пожалуйста.

(no subject)

12/3/08 12:47 (UTC)
Posted by [identity profile] aamonster.livejournal.com
Дык лучше автоматизированный копи-пейст (да еще с подстановками), чем ручной. Как минимум, если изменится шаблон - изменятся и все куски кода, куда он копипастился.

Хотя вопрос не вполне ясен. О какой именно кодогенерации идет речь? О вещах типа примеров из http://rsdn.ru/article/dotnet/codegen.xml ?

P.S. А вообще я склоняюсь к мысли, что если что-то с помощью стороннего кодогенератора делается заметно проще, чем средствами языка - это либо дефект языка, либо использование его средств не по назначению. Особенно сильно на эту мысль наводят библиотеки типа stl/boost (чего стоит одна реализация shared_ptr, не говоря уж о вещах типа boost::lambda): уж больно коряво некоторые вещи реализуются на темплейтах C++.

Сорри за некоторую сумбурность...

(no subject)

12/3/08 13:32 (UTC)
Posted by [identity profile] aamonster.livejournal.com
Ну вот задачка, которую мне довелось решать.
- Дельфи (насколько я могу судить, использование C# или еще какого .net языка ситуацию принципиально не меняет).
- Предопределенный формат файла (лежат поля данных в определенном порядке)
- Есть несколько версий формата файла (различаются по первому полю version)
- Значения полей соответствуют полям или свойствам некоторой формы (включая массивы и биты для boolean-полей).

- Решение "в лоб" #1: написать чтение/запись для каждой версии.
- Решение "в лоб" #2: создать тип данных вроде struct (по типу на каждую версию), написать процедуры переписывания данных из полей/свойств в эту структуру (для каждой версии) и сериализовать ее как массив байт.
- Решение "в духе ООП": создать классы-обвязки для основных типов полей/свойств (с общим предком), создать для каждой версии объект-контейнер (который хранит ссылки на все сериализуемые поля/методы в нужном порядке), в нужный момент создавать такой объект и дергать его методы Load/Save/Import
- Решение, которое выбрал я:
-- Создать для каждой из версий файл, в котором все сериализуемые поля/свойства записаны как строки типа int Form1.Property1
-- Генерить простой код сериализации по этим файлам и включать его директивой include в качестве процедуры.

По сути похоже на ООП-метод, но явно проще.

(no subject)

12/3/08 13:46 (UTC)
Posted by [identity profile] aamonster.livejournal.com
Если я правильно понял, это как раз примерно соответствует предпоследнему (ООП) варианту? (можно подробнее про гибернейтовские маппинги? сойдет ссылка)
Вот только:
1. reflection под рукой не было.
2. кодогенерация в данном случае была _очень_ простой и порождала столь же простой (и достаточно оптимальный - нет нужды раскручивать reflection на каждое сериализуемое поле) код.

Ну и главный вопрос: будет ли при этом описание формата файла не сложнее такого:
--- cut ---
integer TrackBarBrightness.Position
integer TrackBarContrast.Position
integer TrackBarGamma.Position
integer TrackBarScaleX.Position
integer TrackBarScaleY.Position
integer TrackBarVolume.Position
integer TrackBarGain.Position
BeginFlags
Bit SpeedButtonSpectrum.Down
Bit SpeedButtonCurve.Down
Bit SpeedButtonEdge.Down
Bit SpeedButtonFilter.Down
Bit SpeedButtonMirror.Down
Bit SpeedButtonUpsideDown.Down
Bit SpeedButtonMicro.Down
EndFlags
integer Selection1
integer Selection2
integer SpectrumPos
--- cut ---
(что немаловажно, часть integer'ов - поля, часть - свойства, причем не всегда свойства непосредственно сериализуемого объекта)

(no subject)

12/3/08 15:02 (UTC)
Posted by [identity profile] aamonster.livejournal.com
Дык не осложнял... В дельфовской проге у меня было всего 3 версии файла - так что мне понадобилось три раза прогнать генерацию, и все. А так - выткается в make-файл (в общем случае) или в build rules (для visual studio) правило для обработки файлов-шаблонов (ну там, что lex-файлы надо скармливать lex'у), и все.

Да, что я не понял из описания гибернейта: оно генерит оптимальный код или просто работает с объектами через reflection? Так-то, кажется, имеем ровно ту же кодогенерацию, но в рантайме...

(no subject)

13/3/08 07:45 (UTC)
Posted by [identity profile] aamonster.livejournal.com
Выступаю в роли адвоката дьявола :-).

Да, а "оптимизирован" - в смысле, когда мы грузим мапу, она один раз получает ссылки на требуемые поля/методы свойств через reflection, а дальше уже работает напрямую?

На самом деле, грань между кодогенерацией и другими подходами достаточно зыбкая. Можно ведь и генерацию объекта по XML-описанию считать кодогенерацией =).

P.S. А уж что считать кодогенерацией в функциональных языках - просто непонятно =)

(no subject)

12/3/08 20:09 (UTC)
Posted by [identity profile] voidbent.livejournal.com
Проблема с ручным копи-пестом в том, что он приводит к неконтролируемой делокализации сущностей. Кодегенерация - это способ контролировать такую делокализацию в случае если эта делокализация всё таки нужна.

Т.е. кодегенерация - это полезная разновидность копи-пейста.

(no subject)

13/3/08 11:08 (UTC)
Posted by [identity profile] voidbent.livejournal.com
Контролируемая делокализация в промышленных масштабах применяется в основном не для затыкания дыр в суперуниверсальных платформах (не смотря на то, что эти дыры в современных суперуниверсальных платформах имеются в изобилии), а для склеивания неуниверсальных специализированных платформ и технологий (например SQL+HTML).

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

Особенно это актуально для проэктов с заниженными требованиями к атрибутам качества (т.е. к сайтикам и "базкам данных").

Резюме: Неуниверсальные технологии + контролируемая делокализация позволяют удешевить разработку за счёт ухутшения атрибутов качества по сравнению с применением суперуниверсальной технологии.

(no subject)

13/3/08 05:54 (UTC)
Posted by [identity profile] gabriel-irk.livejournal.com
Почему ты всё время говоришь про "дыру в платформе"? Отсутствие рефлекшена - это дыра? Отсутствие замыканий - дыра? Есть ли тогда язык без "дыр"?
Самый распростринённый вариант кодогенерации, ИМХО, макросы Коммон Лиспа (в Схеме есть свои макросы). Там они используются не только для копи-паста, хотя и для него тоже, может даже чаще для него (по сути). На эту тему есть статья "The Art of Metaprogramming". Довольно интересная.
Это не считая использования кодогенерации для всяческой оптимизации.

Кстати, где ссылку ставить?

(no subject)

13/3/08 05:55 (UTC)
Posted by [identity profile] gabriel-irk.livejournal.com
Вспомнил "язык без дыр" - Smalltalk: и рефлекшн есть, и замыкания. :)

(no subject)

14/3/08 04:02 (UTC)
Posted by [identity profile] gabriel-irk.livejournal.com
Ну, про флейм понятно, а про дыры всё ещё нет. Что ты называешь дырами?

В Лиспе главная фича - то, что списком является ВСЁ, и это всё можно модифицировать в рантайме. Правда, не знаю, использует ли эту возможность эоть кто-то в рабочем коде :). Ну, макросы примерно тем же и занимаются...

Вообще, если поискать по википедии, можно найти немало любопытного про кодогенерацию. Например то, что макросы и прочие code snippets во всяких IDE - это тоже кодогенерация. Я эту ммысль вчера недодумал. Хотя, ты наверняка скажешь, что это тот самый копи-паст. На это могу ответить: "включи воображение!" ;).

Ссылку в ЖЖ повесил - заходи посмотри. :)

(no subject)

18/3/08 03:31 (UTC)
Posted by [identity profile] gabriel-irk.livejournal.com
Ну, я-то макросы редакторов использую не особо творчески. В последнее время, для того, чтобы вставлять тэги XML. Кстати, если редактор поддерживает макросы с параметрами - это вообще просто сказка :).

Несколько хороших практичных примеров кодогенерации есть в "Практике программирования" Кернигана и Томпсона.

Что-то я не представляю, каким образом кодогенерацией можно заменить RTTI. Шаблоны, что ли? Я всегда считал, что их смысл несколько в другом, а вообще-то это тоже хороший пример кодогенерации. Если в Java generics сделаны принципиально по-другому, то это зря :).

(no subject)

14/3/08 21:15 (UTC)
Posted by [identity profile] muwlgr.livejournal.com
http://live.gnome.org/Vala

Хороший пример применения кодогенерации там, где она действительно полезна.
Vala - высокоуровневый язык, в основе объектной системы которого лежит Гномовский GObject,
и который транслируется затем в обычный портабельный Си (с правильным юзанием GObjectов,
что делать вручную достаточно трудоёмко).

(no subject)

24/3/08 20:45 (UTC)
Posted by [identity profile] aleksijb.livejournal.com
Раньше я тоже склонялся к мысле о том что кодогенерация от ограничений инструмента. Но тут еще вопрос в том использует ли сам инструмент кодогенерацию. И если использует, и нам надо расширить инструмент, кодогенерация приходит на помощь.
Например является ли рефакторинг кодогенерацией? А если мы добавляем свой рефакторинг?
Или компилятор. Ведь он тоже занимается кодогенерацией. Мы могли бы отказаться от транслирования(кодогенерации) и строить абстракции снизу постепенно слой за слоем, получился бы интерпретатор.
Мне этот вопрос видится в контексте компилятор vs интерпретатор.