Re[3]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.05 08:34
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Я правильно понимаю, что, на самом деле, тебе не решение на Лиспе нужно, а вообще интересуют решения, связанные с кодогенерацией?


Да.

ПК> Если так, смотрел ли ты на то, что используется в KDE?


Нет.

ПК> Например, http://conference2004.kde.org/slides/cornelius.schumacher-metaprogramming.pdf (KConfig XT: XML -> C++).


Посмотрю. Спасибо.
... << RSDN@Home 1.2.0 alpha rev. 565>>
AVK Blog
Re[13]: AST-based solution
От: pvgoran Россия  
Дата: 15.07.05 08:40
Оценка:
Здравствуйте, cranky, Вы писали:

F>>>3) Компактная и простая запись исходных данных и промежуточных результатов

F>>>в виде s-expressions.
C>Что такое "s-expressions"?

И это справшивает человек, который пишет на Lisp'е (точнее, на одном из его диалектов)?

Насколько я понимаю, S-expression — это список, в котором каждый элемент может быть либо "атомом", либо S-expression, причем семантика такого списка определяется его первым элементом.

Программа на Lisp'е — это именно последовательность S-expression'ов (с точностью до всяческих необязательных синтаксических "наворотов" типа '(something)).
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[10]: Lisp
От: pvgoran Россия  
Дата: 15.07.05 08:56
Оценка:
Здравствуйте, AndrewVK, Вы писали:

CP>>Потому что XSLT — это специализированный декларативный язык, созданный для этих целей,


AVK>Не для этого xslt создавался. Он создавался прежде всего для генерации html и xsl:fo по xml-файлам с данными. Вобщем понятно — эффективно предложенную задачу на лиспе не решить.


Это еще почему???
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.05 09:06
Оценка: 4 (3)
Здравствуйте, mishaa, Вы писали:

M>А давайте ее немножко усложним, такую то задачку когда в одном из проектов пришла идея о кодогенерации я решел после пятиминутного чтения xslt титориала, а чуть позже она чуть задача усложнилась, и так с ходу написать преобразование не вышло.


Эээ, тут вобще то лисп обсуждается, а не xslt. Что же касается xslt, то, если тебе интересно, на практике я на нем реализовывал весьма сложные шаблоны.

M>Собствено задача:


M>есть:


M>
M><object name="A">
M>    <extension object="B">
M></object>

M><object name="B">
M>    <extension object="C">
M></object>

M><object name="C"/>
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 невалиден. Я доделал его так:
<objects>
    <object name="A">
      <extension object="B"/>
    </object>
    <object name="B">
      <extension object="C"/>
    </object>
    <object name="C"/>
</objects>

Во-вторых результирующий код тоже невалиден. Я предположил, что ты пропустил объявление базового класса. На основании этого получается такой шаблон:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/objects">
// Recursive templates sample output
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="object">
public class <xsl:value-of select="@name"/>
    <xsl:if test="extension"> : <xsl:value-of select="extension/@object"/></xsl:if>
{
    public static <xsl:call-template name="instance-type">
            <xsl:with-param name="object" select="."/>
        </xsl:call-template> getInstance()
    {
        return <xsl:call-template name="ctor-call">
            <xsl:with-param name="object" select="."/>
        </xsl:call-template>;
    }
}
    </xsl:template>
    
    <xsl:template name="instance-type">
        <xsl:param name="object"/>
        <xsl:choose>
            <xsl:when test="not($object/extension)">
                <xsl:value-of select="$object/@name"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="instance-type">
                    <xsl:with-param name="object" select="/objects/object[@name = $object/extension/@object]"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template name="ctor-call">
        <xsl:param name="object"/>
        <xsl:variable name="not-term" select="$object/extension"/>
        
        <xsl:text>new </xsl:text>
        <xsl:value-of select="$object/@name"/>
        <xsl:text>(</xsl:text>
        <xsl:if test="$not-term">
            <xsl:call-template name="ctor-call">
                <xsl:with-param name="object" select="/objects/object[@name = $object/extension/@object]"/>
            </xsl:call-template>
        </xsl:if>
        <xsl:text>)</xsl:text>
    </xsl:template>
</xsl:stylesheet>


Результат работы:
// Recursive templates sample output
        
public 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();
    }
}
... << RSDN@Home 1.2.0 alpha rev. 565>>
AVK Blog
Re[22]: Lisp
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.07.05 09:09
Оценка:
Здравствуйте, 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++.
Re[10]: Lisp
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 15.07.05 09:12
Оценка:
Здравствуйте, AndrewVK, Вы писали:

ANS>>Ну, если принять за постулат, что Lisp — язык для построения DSL, а XSLT это DSL, то сравнивать их нельзя. Вот разработать тот DSL, который ты хочеш, на LISP, Ruby, C# и сравнить — это да.


AVK>Плохому танцору, как известно, завсегда что то мешает


С этим фактом не поспориш
Есть два вопроса.
Один к тебе: а зачем (как используется) тебе эта генерация.

Второй to ALL: Возможно я какое-то решение пропустил (было мало времени, всё подробно рассматривать).
(Кстати, кто-бы дал ссылки на все приведённые решения на всех языках?).
Но рассмотрим этот файл:

(object "Obj1"
         (property :name "prop1" :type "int")
         (property :name "prop2" :type "string"))


Это по сути Lisp-код. Делаем функцию object, делаем функцию property. И запускаем этот код на выполнение. Результат выполнения — вывод кода. Самому парсить ничего не нужно. Что-то в этом духе было?
... << RSDN@Home 1.1.4 stable rev. 510>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[11]: Lisp
От: mishaa Россия http://kmmbvnr.livejournal.com
Дата: 15.07.05 09:16
Оценка:
Здравствуйте, 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 файл.
-- Главное про деструктор копирования не забыть --
Re[11]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.05 09:16
Оценка:
Здравствуйте, pvgoran, Вы писали:

P>Это еще почему???


Не знаю. Но если пошли отмазки
... << RSDN@Home 1.2.0 alpha rev. 565>>
AVK Blog
Re[11]: Lisp
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 15.07.05 09:17
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Это по сути Lisp-код. Делаем функцию object, делаем функцию property. И запускаем этот код на выполнение. Результат выполнения — вывод кода. Самому парсить ничего не нужно. Что-то в этом духе было?


И про валидатор — другой набор функций (или макр?) результат их выполнения — валидность/невалидность кода.
... << RSDN@Home 1.1.4 stable rev. 510>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[12]: Lisp
От: raskin Россия  
Дата: 15.07.05 09:25
Оценка:
AndrewVK wrote:
> Здравствуйте, pvgoran, Вы писали:
>
> P>Это еще почему???
>
> Не знаю. Но если пошли отмазки

Здесь уже были решения с изменением формата. Сейчас кто-нибудь припомнит
библиотеку — строк на 1000 — производящую полный аккуратный разбор XML в
этот вид (или сам напишет). При этом заявит, что из-за общности размер
неважен, а важна читаемость. После этого сошлётся для описания деталей
генерации на самое изящное из решений с объявлением функции (object
&rest properties)
Posted via RSDN NNTP Server 2.0 beta
Re[4]: Lisp
От: mishaa Россия http://kmmbvnr.livejournal.com
Дата: 15.07.05 09:33
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, mishaa, Вы писали:

AVK>Понятно. Собственно такая задачка может быть решена 2 способами:

Спасибо.

Действительно select="/objects/object[@name = $object/extension/@object]" выглядит вполне красиво. Но в обшем вся сила то оказывается в XPath'е,а а не в XSLT как таковом, и именно XPath оказывается самым человеко читаемым куском программы.
-- Главное про деструктор копирования не забыть --
Re[12]: Lisp
От: Кодёнок  
Дата: 15.07.05 09:36
Оценка:
Здравствуйте, 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, и то же самое на Лиспе.
Re[14]: AST-based solution
От: cranky Украина  
Дата: 15.07.05 09:42
Оценка:
Здравствуйте, pvgoran, Вы писали:

P>Здравствуйте, cranky, Вы писали:


C>>Что такое "s-expressions"?


P>И это справшивает человек, который пишет на Lisp'е (точнее, на одном из его диалектов)?


P>Насколько я понимаю, S-expression — это список, в котором каждый элемент может быть либо "атомом", либо S-expression, причем семантика такого списка определяется его первым элементом.


P>Программа на Lisp'е — это именно последовательность S-expression'ов (с точностью до всяческих необязательных синтаксических "наворотов" типа '(something)).

символьное выражение, что ль? Я лисп исключительно по русским источникам изучал
You aren't expected to absorb this
Re[11]: Lisp
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.07.05 09:42
Оценка: 1 (1)
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>(Кстати, кто-бы дал ссылки на все приведённые решения на всех языках?).


На Lisp-е:
Re[2]: Lisp
Автор: CrazyPit
Дата: 14.07.05
от CrazyPit
Re[4]: Lisp
Автор: cranky
Дата: 14.07.05
от cranky
Re[2]: Lisp
Автор: faulx
Дата: 14.07.05
от faulx (кстати, у него, имхо, получилось самое компактное и читабельное Lisp-решение, а вот оценок ему незаслуженно не поставили. А ведь это первая Lisp-программа была у человека)
Re[2]: AST-based solution
Автор: fionbio
Дата: 14.07.05
от fionbio

И одно было на Ruby:
Re[6]: Lisp
Автор: eao197
Дата: 14.07.05
(только там XML парсился).
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Lisp
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 15.07.05 09:59
Оценка:
Здравствуйте, eao197, Вы писали:

E>На Lisp-е:

E>Re[2]: Lisp
Автор: CrazyPit
Дата: 14.07.05
от CrazyPit

E>Re[4]: Lisp
Автор: cranky
Дата: 14.07.05
от cranky

E>Re[2]: Lisp
Автор: faulx
Дата: 14.07.05
от faulx (кстати, у него, имхо, получилось самое компактное и читабельное Lisp-решение, а вот оценок ему незаслуженно не поставили. А ведь это первая Lisp-программа была у человека)

E>Re[2]: AST-based solution
Автор: fionbio
Дата: 14.07.05
от fionbio


E>И одно было на Ruby:

E>Re[6]: Lisp
Автор: eao197
Дата: 14.07.05
(только там XML парсился).


А на Ocaml & Erlang?
... << RSDN@Home 1.1.4 stable rev. 510>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[13]: Lisp
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.07.05 10:07
Оценка: +1
Здравствуйте, Кодёнок, Вы писали:

Кё>Например, приведённый код на 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++.
Re[13]: Lisp
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.07.05 10:08
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>А на Ocaml & Erlang?


На Ocaml не видел, а Erlang в соседней теме: Re: Задачка: придумать язык
Автор: Gaperton
Дата: 14.07.05
.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: Lisp
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 15.07.05 10:18
Оценка: +1
Здравствуйте, eao197, Вы писали:

ANS>>А на Ocaml & Erlang?


E>На Ocaml не видел, а Erlang в соседней теме: Re: Задачка: придумать язык
Автор: Gaperton
Дата: 14.07.05
.


Ок. благодарю. просто, вроде бы, видел упоминание, что решение на OCaml лучше чем на LISP.
... << RSDN@Home 1.1.4 stable rev. 510>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[23]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.05 10:40
Оценка:
Здравствуйте, eao197, Вы писали:

AVK>>Но как гарантировать что декларативное описание останется декларативным?


E>Никак.


Вот. В этом и проблема. Потому и говорю что подобные фокусы это не совсем то, что хотелось бы видеть.

AVK>> Или как по единственной модели сгенерить несколько исходников?


E>Если коротко, то просто подключить несколько генераторов.


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

E>Если более развертнуто, то я вижу картину так. В общем случае мы имеем какое-то декларативное описание, которое сначала требуется перевести в какое-то внутреннее представление, а затем из внутреннего представления что-то сгенерировать.


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

E> Если мы возьмем в качестве декларативного языка XML, а генераторы будем писать на шарпе, то у нас получается, фактически, три задачи:

E>1) разработать схему XML-деклараций;
E>2) написать парсер XML во внутреннее представление (здесь я имею в виду не синтаксический парсер, а извлечение семантики), т.е. в набор объектов каких-то шарповских типов;

Не обязательно. Во-первых для шарпа xml-байндинг входит в состав фреймворка. Он может и схему сгенерить, и парсинг осуществить. И все практически декларативно.
А во-вторых можно сразу генерить по XML DOM.
... << RSDN@Home 1.2.0 alpha rev. 565>>
AVK Blog
Re[13]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.07.05 10:41
Оценка:
Здравствуйте, raskin, Вы писали:

R>Здесь уже были решения с изменением формата.


Были. Но необходимость изменить формат я лично воспринимаю как недостаток.

R> Сейчас кто-нибудь припомнит R>библиотеку — строк на 1000 — производящую полный аккуратный разбор XML в

R>этот вид (или сам напишет).

Знаешь в чем проблема — в том что это не DSL, для которого такой разбор надо написать один раз. Этот формат создается на коленке под конкретную задачу и в процессе разработки может неоднократно модифицироваться. И что, каждый раз писать эти 1000 строк?
И опять же — вопрос о валидации так и остался повисшим в воздухе.
... << RSDN@Home 1.2.0 alpha rev. 565>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.