Re[16]: Lisp
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.07.05 14:00
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Я не совсем идею понял. Почему тебя не волнует правильность исходных данных?


С чего ты взял что не волнует?

ANS> И всё таки, если прохождение валидации не гарантирует правильность целевого кода, то зачем она нужна?


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

ANS>Если речь идёт о внутрипрограмной генерации, то не проще ли создать генератор с неким API. Который, можно протестировать.


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

ANS> У тебя будет одна точка, где может возникнуть ошибка, а не три.


Каких три?
... << RSDN@Home 1.2.0 alpha rev. 580>>
AVK Blog
Re[17]: Lisp
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 18.07.05 14:31
Оценка:
ANS>> У тебя будет одна точка, где может возникнуть ошибка, а не три.

AVK>Каких три?


Генератор, валидатор, конвертор.

Впрочем, ладно, не зная use-cases я не могу сказать ничего умного
... << RSDN@Home 1.1.4 stable rev. 510>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[3]: Lisp
От: andyJB  
Дата: 18.07.05 16:57
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Покажи как будет выглядить пример с генерацией свойсатв на CamlP4 и Ocaml-е. Думаю, тут всем будет интересно.


А можно ссылку на пример, который нужно переписать?
Re[4]: Lisp
От: andyJB  
Дата: 18.07.05 17:59
Оценка:
Здравствуйте, andyJB, Вы писали:

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



VD>>Покажи как будет выглядить пример с генерацией свойсатв на CamlP4 и Ocaml-е. Думаю, тут всем будет интересно.


JB>А можно ссылку на пример, который нужно переписать?

А понял, из предыдущего ответа.
Решение на Питоне
От: eugals Россия  
Дата: 18.07.05 21:07
Оценка: 29 (5)
Здравствуйте, AndrewVK, Вы писали:

AVK>А можно увидеть на лиспе решение следующей задачи:

AVK>Имеем некое текстовое описание модели каких либо объектов.

Возможно обчеству будет интересно как это было бы удобно делать на Питоне:
Код генератора (test.py):
class CSClass(object):
    @classmethod
    def genSharpCode(csclass):
        props = sorted((n, desc.tp_name) for n, desc in vars(csclass).items() if isinstance(desc, CSProp))
        # заголовок класса
        code = "public class %s\n" % csclass.__name__
        code += "{\n"
        # конструктор
        code += "\tpublic %s(%s)\n" % (csclass.__name__, ", ".join("%s %s" % (t, n) for n, t in props))
        code += "\t{\n"
        for name, _ in props:
            code += "\t\t_%s = %s;\n" % (name, name)
        code += "\t}\n"
        # свойства
        for name, typ in props:
            code += ("\n\tprivate %(typ)s _%(name)s;\n\n" +
                     "\tpublic %(typ)s %(name)s\n" +
                     "\t{\n" +
                     "\t\tget { return _%(name)s; }\n" +
                     "\t}\n") % vars()
        code += "}"
        return code

class CSProp(property):
    def __init__(self, typ):
        self.tp_name = typ.__name__

# объявления поддерживаемых типов свойств (типы int и bool - не описываю, т.к. они уже есть в питоне под нужными именами)
class string(str): pass
class double(float): pass

# разбор параметров запуска
import sys
module = {}
eval(compile(file(sys.argv[1]).read(), sys.argv[1], "exec"), globals(), module)
for csclass in module.itervalues():
    if issubclass(csclass, CSClass):
        print csclass.genSharpCode()

фaйл исходных данных (test.classes):
class Obj1(CSClass):
    prop1 = CSProp(int)
    prop2 = CSProp(bool)

class Obj2(CSClass):
    prop3 = CSProp(string)
    prop4 = CSProp(double)


запускать так:
d:\>python test.py test.classes


Обратите внимание, что для разрешения имен элементов/атрибутов/типов-свойств используется сам интерпретатор питона, который, попутно, очень даже замечательно их все и валидирует.

Результат:
public class Obj1
{
    public Obj1(int prop1, bool prop2)
    {
        _prop1 = prop1;
        _prop2 = prop2;
    }

    private int _prop1;

    public int prop1
    {
        get { return _prop1; }
    }

    private bool _prop2;

    public bool prop2
    {
        get { return _prop2; }
    }
}
public class Obj2
{
    public Obj2(string prop3, double prop4)
    {
        _prop3 = prop3;
        _prop4 = prop4;
    }

    private string _prop3;

    public string prop3
    {
        get { return _prop3; }
    }

    private double _prop4;

    public double prop4
    {
        get { return _prop4; }
    }
}

AVK>Интересует решение именно в духе лиспа.
Кстати, да — вполне в лисповском духе получилось...
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Lisp
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.07.05 23:35
Оценка:
Здравствуйте, andyJB, Вы писали:

JB>А можно ссылку на пример, который нужно переписать?


XSLT-версию найти к сожалению не могу. Но она самая понятная и простая.

Исходная задача
Автор: AndrewVK
Дата: 13.07.05


Реализации на лиспе...
Реализация на Лиспе 1
Автор: fionbio
Дата: 14.07.05
.
Реализация на Лиспе 2
Автор: CrazyPit
Дата: 14.07.05

Реализация на Лиспе 3
Автор: Andrei N.Sobchuck
Дата: 18.07.05


Императивные реализации.
Реализация на C#
Автор: VladD2
Дата: 17.07.05

Реализация на Ruby
Автор: eao197
Дата: 14.07.05


Реализация на Руби совсем лобовая, так что на нее лучше не ориентироваться.
... << RSDN@Home 1.2.0 alpha rev. 578>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Lisp
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.07.05 23:35
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Для какого-нибудь арабского работать не будет. Юникод — дело тонкое...


Она и для русского работает не ахти.
... << RSDN@Home 1.2.0 alpha rev. 578>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Lisp
От: Ka3a4oK  
Дата: 20.07.05 19:46
Оценка:
У меня пара вопросов.

1. На сколько хорош LispWorks Personal Edition? Я так понимаю LispWorks всем лучше LispBox, только он платный ?
2. Можно ли создать исполняемый *.exe модуль программы на лиспе.
3. Cкачал LispBox — не работает OpenFile. Просто какой-то писк, словно ошибка произошла и все.
Что делать?
4. JabberWokly — лажа ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Lisp
От: aefimov Россия
Дата: 21.07.05 16:36
Оценка:
Здравствуйте, fionbio, Вы писали:

F>Напоследок приведу ссылку на одну интересную вещь — пример работы с Common Lisp,

F>в режиме самого что ни на есть interactive development'а. Я уже давал ссылку на
F>статью известного деятеля в области OO, XP и пр. Martin'а Fowler'а:
F>http://martinfowler.com/articles/languageWorkbench.html

Я пытался поработать с MPS, чесно говоря немноо запутался. НЕ могли бы вы ткуть меня носом в книгу/туториал типа:
http://www.jetbrains.com/mps/start/index.html

Я скачал ListWorks, и посмотрел на examples, но даже не смог из запустить. Т.е. не понятно ничего вообще...
Качать мувик не хочется, хочется прочитать и самому написать DSL, пободный JetBrainsсовскому HelloWorld, чтобы
сравнить.

Спасибо!
Re[8]: Lisp
От: cranky Украина  
Дата: 24.07.05 17:46
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>А можно парсер Лиспа в 12 килобайт кода?


В 22К пойдёт? (если там не только парсер):

http://rapidshare.de/files/3318324/rklisp.rar.html

Интерпретатор написан на D+MinTL, ещё не всё реализовано, но пара десятков основных функций и все типы, кроме REAL, работают будто бы неплохо
You aren't expected to absorb this
Re: Решение на Питоне
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.08.05 13:56
Оценка: +1 -1
Здравствуйте, eugals, Вы писали:

E>Кстати, да — вполне в лисповском духе получилось...


Агащазблин. Чистый императив как на Руби, только вместо ХМЛ-я непойми что.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Решение на Питоне
От: eugals Россия  
Дата: 02.08.05 14:35
Оценка:
Здравствуйте, VladD2, Вы писали:

E>>Кстати, да — вполне в лисповском духе получилось...

VD>Агащазблин. Чистый императив как на Руби, только вместо ХМЛ-я непойми что.

Ну, там же написано "в лисповском духе", а не "чисто декларативный разборщик DSL" — почувствуй разницу. Под "лисповским духом" я тут имел ввиду, что в качестве формата исходных данных был использован сам язык высокого уровня (Internal DSL, в определении Фаулера).
Что же касается "ХМЛ" vs "непойми что", то сдается мне ты лукавишь.
Вот это:
class Obj1(CSClass):
    prop1 = CSProp(int)
    prop2 = CSProp(string)

вряд ли более "непонятно", чем вот это:
<objects>
    <object name="Obj1">
        <property name="prop1" type="int"/>
        <property name="prop2" type="string"/>
    </object>
</objects>

... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Решение на Питоне
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.08.05 06:41
Оценка: -1
Здравствуйте, eugals, Вы писали:

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


E>>>Кстати, да — вполне в лисповском духе получилось...

VD>>Агащазблин. Чистый императив как на Руби, только вместо ХМЛ-я непойми что.

E>Ну, там же написано "в лисповском духе", а не "чисто декларативный разборщик DSL" — почувствуй разницу.


Думаю "в лисповском духе" как раз и подразумевает декларативность. Можно спросить у АВК.

E> Под "лисповским духом" я тут имел ввиду, что в качестве формата исходных данных был использован сам язык высокого уровня


Думаю, что это как раз самое плохое в лисповском коде.

E>Что же касается "ХМЛ" vs "непойми что", то сдается мне ты лукавишь.


А мне сдается что ты.

E>Вот это:

E>
E>class Obj1(CSClass):
E>    prop1 = CSProp(int)
E>    prop2 = CSProp(string)
E>

E>вряд ли более "непонятно", чем вот это:
E>
E><objects>
E>    <object name="Obj1">
E>        <property name="prop1" type="int"/>
E>        <property name="prop2" type="string"/>
E>    </object>
E></objects>
E>

E>)

Первое не очевидно. Если человек не знает Питона, так вообще непойми что. Второе описание я понял без объяснений.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Lisp
От: pongo  
Дата: 12.09.05 23:45
Оценка: 18 (1)
Здравствуйте, AndrewVK, Вы писали:

AVK>А можно увидеть на лиспе решение следующей задачи:

AVK>Имеем некое текстовое описание модели каких либо объектов. Пусть это будет xml. Например:

Быть может, уже поздно. Но хочу предложить свое решение на Ruby

class MyObject
    def initialize(name)
        @name = name
        @propertys = []
    end

    def to_s
        str = ""
        str += "public class #@name\n"
        str += "{\n"               
        
        str += "    public #@name("
        @propertys.each_index { |x|
            str += "#{@propertys[x]['type']} #{@propertys[x]['name']}"
            str += ", " if x < @propertys.length - 1
        }
        str += ")\n"
        
        
        str += "    {\n"
            @propertys.each { |item|
                str += "        _#{item['name']} = #{item['name']};\n"
            }
        str += "    }\n"

        @propertys.each { |item|
            str += "    \n"
            str += "    private #{item['type']} _#{item['name']};\n\n"
            str += "    public #{item['type']} #{item['name'].capitalize}\n"
            str += "    {\n"
            str += "        get { return _#{item['name']}; } \n"
            str += "    }\n"
        }
            
        str += "}\n"
    end
    
    def AddProperty(type, name)
        @propertys += [ { 'type' => type, 'name' => name } ]
    end
end

def _object(name)
    $obj = MyObject.new(name)
    
    yield
    
    print $obj
end

def _property(type, name)
    $obj.AddProperty(type, name)
end

# описание модели

_object("Obj1") {
    _property("int", "prop1")
    _property("string", "prop2")
}


Выводит:
public class Obj1
{
    public Obj1(int prop1, string prop2)
    {
        _prop1 = prop1;
        _prop2 = prop2;
    }
    
    private int _prop1;

    public int Prop1
    {
        get { return _prop1; } 
    }
    
    private string _prop2;

    public string Prop2
    {
        get { return _prop2; } 
    }
}


Итак, руби -- язык интерпретируемый? Значит можно написать всё на самом языке... Надеюсь я понятно выразился

Ps. Это мой первый опыт программирования на руби. Буквально сегодня я начал его изучать, прочитал пока пару статей...
Re[3]: Lisp
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.09.05 05:09
Оценка: 1 (1)
Здравствуйте, pongo, Вы писали:

P>Ps. Это мой первый опыт программирования на руби. Буквально сегодня я начал его изучать, прочитал пока пару статей...


Ура!!! Полку Rubyist-ов на RSDN прибывает!

Позволю себе пару комментариев по твоему посту. Во-первых, ты выбрал не самый удачный вариант DSL. Можно было бы сделать либо так:
object :Obj1 {
    property :int, :prop1
    property :string, :prop2
}

этот вариант реализуюется с помощью instance_eval вместо yield.
Либо можно применить подход с передачей параметров в блок:
object :Obj1 { |o|
    o.property :int, :prop1
    o.property :string, :prop2
}

Пример того, как это реализуется и работает я приводил вот здесь: Re: Использование метаданных в программах на языке C++
Автор: eao197
Дата: 08.09.05
.
Ну и в твоем варианте можно было вполне обойтись без глобальной переменной.

Во-вторых, Ruby, имхо, лучше изучать не по статьям, а по книге "Programming Ruby: The Pragmatic Programmer's Guide". Ее первое издание свободно доступно на rubycentral.com и, более того, идет в OneClickRubyInstaller. Недавно вышло второе издание. В электронном виде (PDF) доступно только через eMule . Но, имхо, даже первое издание дает очень хорошее представление о языке и о том, как его можно использовать. Например, год назад, имея под рукой только первое издание, я сделал свой Mxx_ru, а там Ruby как раз в качестве DSL и применяется.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Lisp
От: pongo  
Дата: 13.09.05 09:58
Оценка:
Здравствуйте, eao197, Вы писали:

E>Позволю себе пару комментариев по твоему посту.


я сделал так, как позволили мои знания. В общем, надо будет это изучить

E>Ну и в твоем варианте можно было вполне обойтись без глобальной переменной.

Знаю.

E>Во-вторых, Ruby, имхо, лучше изучать не по статьям, а по книге "Programming Ruby: The Pragmatic Programmer's Guide".

до неё я еще не дошел. Как не дошел и до DSL. Читал про DSL только маленькую статью в одном блоге...
Re[4]: Смеха ради
От: vdimas Россия  
Дата: 10.12.05 19:42
Оценка:
Здравствуйте, CrazyPit, Вы писали:

Смеха ради можно попользовать макросы из С. Прогонять только препроцессором.

Вот программа:
#define CLASS(name, properties)\
public class name {\
properties\
}

#define BASE(name) : name

#define PROP(type, name)\
  type _##name;\
  type name { \
    get {return _##name; }\
    set { _##name = value; }\
}


Вот на входе:
CLASS(SomeClass BASE(BaseClass), 
    PROP(int, Prop1) 
    PROP(string, Prop2))


Вот на выходе (после форматирования):
     public class SomeClass : BaseClass {
        int _Prop1;
        int Prop1 {
            get { return _Prop1; }
            set { _Prop1 = value; }
        }

        string _Prop2;
        string Prop2 {
            get { return _Prop2; }
            set { _Prop2 = value; }
        }
    }
Re[2]: Решение на Ruby DSL.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 26.02.06 06:05
Оценка: 8 (1)
Прошу прощения, что поднимаю эту тему, но в разговоре про Nemerle
Автор: Oyster
Дата: 23.02.06
был проявлен интерес к тому, как решение подобной задачи могло выглядеть на Ruby (Ruby как DSL вместо XML, результирующий код так же генерируется для Ruby).

# Подключаем Pretty Printer для печати содержимого объектов.
require 'pp'

### Начало реализации DSL

# Объект этого типа будет аккумулировать метаописание.
class ObjectDesc
  attr_reader :name
  attr_reader :properties

  def initialize( name )
    @name = name
    @properties = []
  end

  def property( name )
    @properties << name
  end
end

# Генератор описания класса из метаописания.
def generate( o )
  c = %Q{
class #{o.name}
#{o.properties.inject('') { |r,p| r << "  attr_accessor :#{p}\n"; r }}
  def initialize( #{o.properties.join(', ')} )
#{o.properties.inject('') { |r,p| r << "    @#{p} = #{p}\n"; r }}
  end
end
}
  c
end

# Это и есть элемент специализированного DSL-я.
def object( name, &blk )
  o = ObjectDesc.new( name )
  o.instance_eval( &blk )

  eval generate( o )
end

### Начало использования DSL

# Задаем метаописание пустого класса посредством DSL.
object "Empty" do
end

# Задаем метаописание первого класса посредством DSL.
object "First" do
  property :first
  property :second
  property :a
end

### Проверка того, что класс Fisrt действительно доступен для разработчика.

# Работаем с уже определенным классом.
f = First.new( 'a', 'b', 'c' )
pp f
f.first = "aa"
f.second = "bb"
pp f


В результате получаем:
#<First:0x2805a68 @a="c", @first="a", @second="b">
#<First:0x2805a68 @a="c", @first="aa", @second="bb">


Собственно сам DSL -- это обращение к функции object:
object "First" do
  property :first
  property :second
  property :a
end

из которого функция generate создает текст вида:

class First
  attr_accessor :first
  attr_accessor :second
  attr_accessor :a

  def initialize( first, second, a )
    @first = first
    @second = second
    @a = a

  end
end

а функция object вычисляет его через eval. Таким образом, внутри object() описание нового класса становится доступным для Ruby-программы.

Функция generate могла иметь и чуть более простой вид (с меньшим количеством обращений к string interpolation):
def generate( o )
  c = String.new
  c << "class #{o.name}\n"
  o.properties.each { |p| c << "  attr_accessor :#{p}\n" }
  c << "  def initialize( #{o.properties.join(', ')} )\n"
  o.properties.each { |p| c << "    @#{p} = #{p}\n" }
  c << "  end\n"
  c << "end\n"
  c
end

к тому же она строит код без лишних пустых строк:
class First
  attr_accessor :first
  attr_accessor :second
  attr_accessor :a
  def initialize( first, second, a )
    @first = first
    @second = second
    @a = a
  end
end


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: Lisp
От: Dr.Gigabit  
Дата: 26.02.06 17:22
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> C>В-третьих, для обычных языков типа Java/C# уже существуют системы для

>> C>редактирования AST. Только называется это Aspect Oriented
>> Programming. А
>> C>для C# у нас еще и R# есть
>> Не есть — а недавно появилось...

Ваши представления об АОП несколько искажены.

C>AspectJ появился в 99 (если не ошибаюсь), до этого были исследования на

C>эту тему в PARC'е.

>> Что еше раз потверждает выше сказанную мысль о том что все языки

>> медленно двигаются в сторону Лиспа.
>> Меня собственно и подвигло на серьезноге изучение Лиспа, так это то
>> что в CLOS кажись заложенно и AOP .

C>Кстати, после нескольких лет увлечения AOP сейчас интерес к нему

C>угасает.

Достаточно сюда глянуть.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Решение на Ruby DSL.
От: Oyster Украина https://github.com/devoyster
Дата: 27.02.06 16:18
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>Прошу прощения, что поднимаю эту тему, но в разговоре про Nemerle
Автор: Oyster
Дата: 23.02.06
был проявлен интерес к тому, как решение подобной задачи могло выглядеть на Ruby (Ruby как DSL вместо XML, результирующий код так же генерируется для Ruby).


Спасибо за код. Я так понял, что Ruby — язык с динамической типизацией?

В общем-то, не нравится мне в его средствах метапрограммирования то, что они недалеко ушли от сишных макросов — фактически мы собираем код в текстовом виде. Со всеми вытекающими в виде отсутствия контроля типов в компайл-тайм (но в Ruby-то этого и так нет, если я всё правильно понимаю) и невнятных ошибок в случае, если что-то генерится неверно (на простом примере можно и глазками посмотреть, а вот на сложном...).

Ну и ещё не нравится то, что нельзя оперировать кусками AST, т.к. это может быть очень полезно (ну там — пройтись по AST рекурсивно и сделать что-нибудь для нодов определённого типа). Или можно, но в коде это не использовалось?

Ну а нравится, соответственно, неограниченная гибкость — пиши что хочешь и как хочешь. В общем, макросы Nemerle — это строготипизированный подход к метапрограммированию
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.