Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Я правильно понимаю, что, на самом деле, тебе не решение на Лиспе нужно, а вообще интересуют решения, связанные с кодогенерацией?
Да.
ПК> Если так, смотрел ли ты на то, что используется в KDE?
Здравствуйте, cranky, Вы писали:
F>>>3) Компактная и простая запись исходных данных и промежуточных результатов F>>>в виде s-expressions. C>Что такое "s-expressions"?
И это справшивает человек, который пишет на Lisp'е (точнее, на одном из его диалектов)?
Насколько я понимаю, S-expression — это список, в котором каждый элемент может быть либо "атомом", либо S-expression, причем семантика такого списка определяется его первым элементом.
Программа на Lisp'е — это именно последовательность S-expression'ов (с точностью до всяческих необязательных синтаксических "наворотов" типа '(something)).
Здравствуйте, AndrewVK, Вы писали:
CP>>Потому что XSLT — это специализированный декларативный язык, созданный для этих целей,
AVK>Не для этого xslt создавался. Он создавался прежде всего для генерации html и xsl:fo по xml-файлам с данными. Вобщем понятно — эффективно предложенную задачу на лиспе не решить.
Здравствуйте, mishaa, Вы писали:
M>А давайте ее немножко усложним, такую то задачку когда в одном из проектов пришла идея о кодогенерации я решел после пятиминутного чтения xslt титориала, а чуть позже она чуть задача усложнилась, и так с ходу написать преобразование не вышло.
Эээ, тут вобще то лисп обсуждается, а не xslt. Что же касается xslt, то, если тебе интересно, на практике я на нем реализовывал весьма сложные шаблоны.
M>Собствено задача:
M>есть:
M>
M>class A
M>{
M> public static C getInstance()
M> {
M> return new A(new B(new C()));
M> }
M>}
M>class B
M>{
M> public static C getInstance()
M> {
M> return new B(new C());
M> }
M>}
M>class C
M>{
M> public static C getInstance()
M> {
M> return new C();
M> }
M>}
M>
Понятно. Собственно такая задачка может быть решена 2 способами:
1) Избавиться от явной рекурсивности путем перепроектирования того, что должно генерироваться. Например в твоем случае можно было бы заменить код вызова конструктора на такой (для класса A)
return new A((B)B.getInstance());
В этом случае написать шаблон не составит труда даже новичку.
2) Написать рекурсивный шаблон.
Рекурсивный вариант я продемонстрирую. Правда несколько поправок. Во-первых твой xml невалиден. Я доделал его так:
// Recursive templates sample outputpublic class A : B
{
public static C getInstance()
{
return new A(new B(new C()));
}
}
public class B : C
{
public static C getInstance()
{
return new B(new C());
}
}
public class C
{
public static C getInstance()
{
return new C();
}
}
Здравствуйте, AndrewVK, Вы писали:
E>>Нет, я предлагал делать декларативное описание сразу на Руби. В этом случае валидатором (по крайней мере синтаксическим) будет сам Руби.
AVK>Но как гарантировать что декларативное описание останется декларативным?
Никак. Все-таки это просто использование возможности языка программирования для создания декларативных описаний. И я не знаю, как в таком описании запретить кому-нибудь написать if или while. Думаю, что это вообще не возможно.
AVK> Или как по единственной модели сгенерить несколько исходников?
Если коротко, то просто подключить несколько генераторов.
Если более развертнуто, то я вижу картину так. В общем случае мы имеем какое-то декларативное описание, которое сначала требуется перевести в какое-то внутреннее представление, а затем из внутреннего представления что-то сгенерировать. Если мы возьмем в качестве декларативного языка XML, а генераторы будем писать на шарпе, то у нас получается, фактически, три задачи:
1) разработать схему XML-деклараций;
2) написать парсер XML во внутреннее представление (здесь я имею в виду не синтаксический парсер, а извлечение семантики), т.е. в набор объектов каких-то шарповских типов;
3) написать генератор использующий внутреннее представление.
В случае Ruby у нас опять есть две похожие задачи:
1) придумать такие Ruby классы, создание объектов которых в неком Ruby-скрипте будет являтся нужным декларативным описанием. Фактически, это есть объединение задач 1-2 из подхода с использованием XML и шарпа. Но в результате исполнения скрипта с декларативными описаниями мы сразу получаем необходимое внутренне представление;
2) написать генератор использующий внутреннее представление.
Понятно, что генераторов можно создать сколько угодно. Как их комбинировать с декларативными скриптами -- это уже технические детали, имхо. Можно на вход Ruby подавать скрипт-генератор и указывать в качестве аргумента декларативный скрипт. А можно наоборот, отдавать Ruby декларативный скрипт и передавать ему аргументом имя генератора(ов). А можно сделать третий скрипт, который передается Ruby и которому, в качестве аргументов, указываются и декларативный скрип и генератор(ы).
Имхо, достоинства Ruby-декларативности в том, что промежуточных действий меньше, все делается на одном простом языке. Все всегда доступно в иходниках, всегда можно что-то подкрутить, поправить. Генерировать что-либо на Ruby не сложно, я думаю, это было показано моим примером.
Эти же достоинства оборачиваются и недостатками. Мы не можем гарантировать, что скрипты будут декларативными. Мы не можем использовать продвинутые редакторы с подсказками (как в случае XML с XSD). Мы не можем декларацию обработать программой на другом языке. Хотя, при необходимости, можно будет сделать генератор из Ruby куда-то еще (но нужно ли тогда с Ruby вообще связываться ?).
Вот такие дела. Никаких однозначных преимуществ Ruby перед связкой XML-C# я не вижу. Но сделать на Ruby такую штуку можно и я просто об этом сказал, совершенно не настаивая на том, что так нужно делать.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
ANS>>Ну, если принять за постулат, что Lisp — язык для построения DSL, а XSLT это DSL, то сравнивать их нельзя. Вот разработать тот DSL, который ты хочеш, на LISP, Ruby, C# и сравнить — это да.
AVK>Плохому танцору, как известно, завсегда что то мешает
С этим фактом не поспориш
Есть два вопроса.
Один к тебе: а зачем (как используется) тебе эта генерация.
Второй to ALL: Возможно я какое-то решение пропустил (было мало времени, всё подробно рассматривать).
(Кстати, кто-бы дал ссылки на все приведённые решения на всех языках?).
Но рассмотрим этот файл:
Это по сути Lisp-код. Делаем функцию object, делаем функцию property. И запускаем этот код на выполнение. Результат выполнения — вывод кода. Самому парсить ничего не нужно. Что-то в этом духе было?
Здравствуйте, pvgoran, Вы писали:
P>Здравствуйте, AndrewVK, Вы писали:
AVK>>Не для этого xslt создавался. Он создавался прежде всего для генерации html и xsl:fo по xml-файлам с данными. Вобщем понятно — эффективно предложенную задачу на лиспе не решить.
P>Это еще почему???
К чему вопрос? Почему xslt не предназначен? Ну хотя бы потому что банальный вызов шаблона с парочкой параметров может быть длиннее самого шаблона, да и если на выходе хочется получить нормально отформатированные исходники то начинаются танцы с бубном.
Ну а если про лисп. То не вижу причин не реализовать спомошью лисповских макросов что-то типа:
(xsl:apply-templates (match '(object (property)))
(format t "class ~a" *curr-tag*))
На выходе имем
1) Возможность писать внутри шаблонов в императивном стиле
2) Все тот же лисп, а значит есть полная поддержка со стороны ide и деббагера.
Реализация получается ни чуть не сложнее чем у связки XSLT трансформер + XSLT файл.
-- Главное про деструктор копирования не забыть --
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Это по сути Lisp-код. Делаем функцию object, делаем функцию property. И запускаем этот код на выполнение. Результат выполнения — вывод кода. Самому парсить ничего не нужно. Что-то в этом духе было?
И про валидатор — другой набор функций (или макр?) результат их выполнения — валидность/невалидность кода.
AndrewVK wrote: > Здравствуйте, pvgoran, Вы писали: > > P>Это еще почему??? > > Не знаю. Но если пошли отмазки
Здесь уже были решения с изменением формата. Сейчас кто-нибудь припомнит
библиотеку — строк на 1000 — производящую полный аккуратный разбор XML в
этот вид (или сам напишет). При этом заявит, что из-за общности размер
неважен, а важна читаемость. После этого сошлётся для описания деталей
генерации на самое изящное из решений с объявлением функции (object
&rest properties)
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, mishaa, Вы писали: AVK>Понятно. Собственно такая задачка может быть решена 2 способами:
Спасибо.
Действительно select="/objects/object[@name = $object/extension/@object]" выглядит вполне красиво. Но в обшем вся сила то оказывается в XPath'е,а а не в XSLT как таковом, и именно XPath оказывается самым человеко читаемым куском программы.
-- Главное про деструктор копирования не забыть --
Здравствуйте, mishaa, Вы писали:
M>Ну а если про лисп. То не вижу причин не реализовать спомошью лисповских макросов что-то типа:
M>(xsl:apply-templates (match '(object (property))) M> (format t "class ~a" *curr-tag*))
Я вообще не понимаю, о чем дискуссия.
Например, приведённый код на Ruby, например, можно транслировать в Лисп, если предположить, что в нём есть такая же XML-библиотека, и получится короткая программа, которая ну никак не отражает ни специфику Ruby, на Лиспа. Мы сможем разве что сравнить синтаксический сахар Ruby `coll do |e|` против (dolist ...) и `puts` против (format ...), что большой информации не даёт
Обсуждать связку XML+XSLT против Лиспа некорректно, потому что первые два языки специального назначения, а второй — общего. Всё равно что обсуждать один оператор пёрла `$s =~ /(foo){2,10}/i` против многих страниц _реализации_ этих самых регулярных выражений. Куда интереснее сравнить, например, декларацию + трансформер на самом языке (Ruby например), без привлечения XML, и то же самое на Лиспе.
Здравствуйте, pvgoran, Вы писали:
P>Здравствуйте, cranky, Вы писали:
C>>Что такое "s-expressions"?
P>И это справшивает человек, который пишет на Lisp'е (точнее, на одном из его диалектов)?
P>Насколько я понимаю, S-expression — это список, в котором каждый элемент может быть либо "атомом", либо S-expression, причем семантика такого списка определяется его первым элементом.
P>Программа на Lisp'е — это именно последовательность S-expression'ов (с точностью до всяческих необязательных синтаксических "наворотов" типа '(something)).
символьное выражение, что ль? Я лисп исключительно по русским источникам изучал
от faulx (кстати, у него, имхо, получилось самое компактное и читабельное Lisp-решение, а вот оценок ему незаслуженно не поставили. А ведь это первая Lisp-программа была у человека) Re[2]: AST-based solution
от faulx (кстати, у него, имхо, получилось самое компактное и читабельное Lisp-решение, а вот оценок ему незаслуженно не поставили. А ведь это первая Lisp-программа была у человека) E>Re[2]: AST-based solution
Здравствуйте, Кодёнок, Вы писали:
Кё>Например, приведённый код на Ruby, например, можно транслировать в Лисп, если предположить, что в нём есть такая же XML-библиотека, и получится короткая программа, которая ну никак не отражает ни специфику Ruby, на Лиспа. Мы сможем разве что сравнить синтаксический сахар Ruby `coll do |e|` против (dolist ...) и `puts` против (format ...), что большой информации не даёт
Почему же? Для некоторых это может стать причиной выбора в пользу того или иного языка. Например, конструкция "call do |e|" в свое время склонила для меня чашу весов в пользу Ruby, а не Perl-а или Python-а.
Кё>Куда интереснее сравнить, например, декларацию + трансформер на самом языке (Ruby например), без привлечения XML, и то же самое на Лиспе.
А вот это, может быть и интереснее, но бессмысленнее. Инструмент должен хорошо решать ту задачу, для которой он предназначен. XML -- отличная штука для декларативности (если конечно инструменты соответствующие применять). Ruby -- отличная штука для программирования. То, что на Ruby можно достигать декларативности -- это всего лишь бонус вышеупомянутого тобой синтаксического сахара. Но связка из нескольких специализированных инструментов (XML, XML-editor, Ruby) дает отличные результаты. Кстати, REXML -- это стандартная библиотека Ruby для работы с XML, которая входит непосредственно в дистрибутив Ruby 1.8.2 и для работы с XML в Ruby не нужно искать дополнительные иструменты, хотя и такие имеются.
В то же время Lisp позволяет делать и декларацию и реализацию. Результат мы все увидели. No comments.
Вот чего мы не увидели, так это решение исходной задачи, включая парсинг XML-я, на Lisp-е. А жаль. Но может еще есть надежда?
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
AVK>>Но как гарантировать что декларативное описание останется декларативным?
E>Никак.
Вот. В этом и проблема. Потому и говорю что подобные фокусы это не совсем то, что хотелось бы видеть.
AVK>> Или как по единственной модели сгенерить несколько исходников?
E>Если коротко, то просто подключить несколько генераторов.
Подожди. Но у тебя конкретная конструкция будет интерпретироваться однозначно, либо кодогенерацию придется вводить дискриминатор, показывающий что собственно мы сейчас генерим.
E>Если более развертнуто, то я вижу картину так. В общем случае мы имеем какое-то декларативное описание, которое сначала требуется перевести в какое-то внутреннее представление, а затем из внутреннего представления что-то сгенерировать.
Вот видишь, мы и вернулись в начало. Т.е. чтобы получить качественный результат, нужно двойное преобразование. А в этом случае, как я уже говорил, с этим справится любой нормальный императивный язык.
E> Если мы возьмем в качестве декларативного языка XML, а генераторы будем писать на шарпе, то у нас получается, фактически, три задачи: E>1) разработать схему XML-деклараций; E>2) написать парсер XML во внутреннее представление (здесь я имею в виду не синтаксический парсер, а извлечение семантики), т.е. в набор объектов каких-то шарповских типов;
Не обязательно. Во-первых для шарпа xml-байндинг входит в состав фреймворка. Он может и схему сгенерить, и парсинг осуществить. И все практически декларативно.
А во-вторых можно сразу генерить по XML DOM.
Здравствуйте, raskin, Вы писали:
R>Здесь уже были решения с изменением формата.
Были. Но необходимость изменить формат я лично воспринимаю как недостаток.
R> Сейчас кто-нибудь припомнит R>библиотеку — строк на 1000 — производящую полный аккуратный разбор XML в R>этот вид (или сам напишет).
Знаешь в чем проблема — в том что это не DSL, для которого такой разбор надо написать один раз. Этот формат создается на коленке под конкретную задачу и в процессе разработки может неоднократно модифицироваться. И что, каждый раз писать эти 1000 строк?
И опять же — вопрос о валидации так и остался повисшим в воздухе.