Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 24.05.11 21:32
Оценка:
Скажите, насколько сложен такой финт ушами? Планируете ли?
Re: Генерация C# кода из Nemerle
От: Ziaw Россия  
Дата: 25.05.11 04:30
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Скажите, насколько сложен такой финт ушами? Планируете ли?


Какая генерация имеется ввиду? Текстовая? Если текстовая — можно попробовать сделать преобразование AST в строку в виде C#. Не все можно преобразовать, но если ограничивать конструкции — вполне можно генерить. Но текст это плохое решение.

Но nemerle умеет компилировать C#, при этом будут работать макросы уровня сборки и атрибутные. Эти макросы могут генерить что угодно на этапе компиляции.
Re[2]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 06:02
Оценка: 6 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Какая генерация имеется ввиду? Текстовая? Если текстовая — можно попробовать сделать преобразование AST в строку в виде C#. Не все можно преобразовать, но если ограничивать конструкции — вполне можно генерить. Но текст это плохое решение.


Да, имеется ввиду генереация текста на C# из AST Nemerle. Насколько это сложно (по времени)?

Z>Но nemerle умеет компилировать C#, при этом будут работать макросы уровня сборки и атрибутные. Эти макросы могут генерить что угодно на этапе компиляции.


Я просто подумал, что если вы можете в одну сторону C# -> Nemerle сконвертировать, то может быть можно и в обратную сторону?
Возможно я ошибаюсь, но мне кажется, что при наличии такой фичи людям было бы значительно проще общаться с работодателем, т.к. они бы могли уже сейчас начать спокойно играться с алгебраическими типами Nemerle, его макросами, например computation expressions, т.к. могли бы в любой момент свои наработки на Nemerle перевести в C# , что-то допилить и включить в C# проекты (понимаю, что кода там будет побольше и может быть не все будет выглядеть красиво). Т.е. у людей всегда был бы выбор или убедить своих, как все круто на Nemerle или, если упрутся, загенерить C# код и допиливать уже только его. Чисто стратегически это могло бы вывести часть теоретиков в разряд практиков, т.е. большее число людей могло бы спокойней играться с Nemerle и подтягивать других, т.к. мнение работодателя бы здесь играло значительно меньшую роль.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[3]: Генерация C# кода из Nemerle
От: hardcase Пират http://nemerle.org
Дата: 25.05.11 06:06
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Да, имеется ввиду генереация текста на C# из AST Nemerle. Насколько это сложно (по времени)?


В общем случае это очень хреново реализуемо — ибо match. А вообще лучше плагин к ILSpy наваяать, который бы понимал немерловые лямбды и match.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 06:12
Оценка:
Здравствуйте, hardcase, Вы писали:

H>В общем случае это очень хреново реализуемо — ибо match. А вообще лучше плагин к ILSpy наваяать, который бы понимал немерловые лямбды и match.


А разве тот же match не разворачивается в итоге в дерево if/else в понимании C#?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[5]: Генерация C# кода из Nemerle
От: hardcase Пират http://nemerle.org
Дата: 25.05.11 06:18
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>А разве тот же match не разворачивается в итоге в дерево if/else в понимании C#?


Не всегда. Он может и в switch развернуться. Но ты посмотри декомпилированные match-и Такой код человеки не пишут и уж тем более не поддерживают.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Генерация C# кода из Nemerle
От: Ziaw Россия  
Дата: 25.05.11 06:20
Оценка:
Здравствуйте, Димчанский, Вы писали:

H>>В общем случае это очень хреново реализуемо — ибо match. А вообще лучше плагин к ILSpy наваяать, который бы понимал немерловые лямбды и match.


Д>А разве тот же match не разворачивается в итоге в дерево if/else в понимании C#?


Разворачивать-то придется тебе. Вполне можешь в if/else. Поскольку AST будешь строить тоже ты, особых проблем с разворачиванием я не вижу.
Re[6]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 06:24
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Не всегда. Он может и в switch развернуться. Но ты посмотри декомпилированные match-и Такой код человеки не пишут и уж тем более не поддерживают.


Ну я только вчера поставил Nemrle, накидал по-быстрому рекурсивную функцию фибоначи с аккумуляторами, посмотрел в ILSpy как выглядит — вполне нормальный while цикл получился.
Вот когда алгебраические типи матчить или что еще посложнее, то конечно там должно получаться что-то страшное. А с другой стороны, если бы на C# кто-то бы пытался те же самые алгебраические типы данных изобразить и работать с ними, неужели бы у него код получился бы сильно красивее?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[6]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 06:30
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Разворачивать-то придется тебе. Вполне можешь в if/else. Поскольку AST будешь строить тоже ты, особых проблем с разворачиванием я не вижу.


Ты выше писал: "Не все можно преобразовать, но если ограничивать конструкции — вполне можно генерить."
Я просто пытаюсь понять, что именно не получится преобразовать в код на C#?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re: Генерация C# кода из Nemerle
От: catbert  
Дата: 25.05.11 06:45
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Скажите, насколько сложен такой финт ушами? Планируете ли?


Мне кажется, это не слишком сложно, но из-за некоторых особенностей языка (матч и возможно хвостовая рекурсия) сгенерированный код будет не таким эффективным, как в Немерле.

Влад говорил в видео
Автор: Ka3a4oK
Дата: 19.05.11
, что хотелось бы эту фичу реализовать.
Re[2]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 07:00
Оценка:
Здравствуйте, catbert, Вы писали:

C>Мне кажется, это не слишком сложно, но из-за некоторых особенностей языка (матч и возможно хвостовая рекурсия) сгенерированный код будет не таким эффективным, как в Немерле.


По словам Влада, хвостовые рекурсии в Nemerle разворачиваются в циклы, т.е. не используется IL tail call иснтрукция, т.к. он медленнее. Поэтому с рекурсией видимо не должно быть больших проблем.

C>Влад говорил в видео
Автор: Ka3a4oK
Дата: 19.05.11
, что хотелось бы эту фичу реализовать.


Да, я краем ухал слышал про это в видео, но хотел уточнить у первоисточников.
Может сам Влад что-то напишет об этом здесь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[7]: Генерация C# кода из Nemerle
От: Ziaw Россия  
Дата: 25.05.11 07:01
Оценка:
Здравствуйте, Димчанский, Вы писали:

Z>>Разворачивать-то придется тебе. Вполне можешь в if/else. Поскольку AST будешь строить тоже ты, особых проблем с разворачиванием я не вижу.


Д>Ты выше писал: "Не все можно преобразовать, но если ограничивать конструкции — вполне можно генерить."

Д>Я просто пытаюсь понять, что именно не получится преобразовать в код на C#?

Получится все. Только некоторые вещи, типа разворачивания сложных паттернов в if-ы, нелегко. Но если ты не захочешь генерить эти паттерны проблем нет. Для примера текстовой генерации можно посмотреть http://code.google.com/p/nemerle/source/browse/nemerle/trunk/ncc/misc/PrettyPrint.n

А чем тебе не нравится идея компайл-тайм генерации? Nemerle под нее прекрасно заточен, а вот текстовую придется пилить самостоятельно. Изобретать разные пребилд скрипты. Форматировать этот текст. При этом никакого анализа окружения. Хотя, можно распарсить, конечно.
Re[3]: Генерация C# кода из Nemerle
От: Ziaw Россия  
Дата: 25.05.11 07:20
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>По словам Влада, хвостовые рекурсии в Nemerle разворачиваются в циклы, т.е. не используется IL tail call иснтрукция, т.к. он медленнее. Поэтому с рекурсией видимо не должно быть больших проблем.


Кстати, ктонибудь тестил ее в .Net4? Они ее оптимизировали вроде. Кто на ты с IL, потестите плиз.
Re[8]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 08:19
Оценка:
Здравствуйте, Ziaw, Вы писали:

Спасиб за пример, на досуге посмотрю.

Z>А чем тебе не нравится идея компайл-тайм генерации? Nemerle под нее прекрасно заточен, а вот текстовую придется пилить самостоятельно. Изобретать разные пребилд скрипты. Форматировать этот текст. При этом никакого анализа окружения. Хотя, можно распарсить, конечно.


Видишь, я еще не совсем в теме, поэтому не очень понимаю, что значит компайл-тайм генерация. Как это выглядит? Может пример есть?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[4]: Генерация C# кода из Nemerle
От: WolfHound  
Дата: 25.05.11 09:11
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Кстати, ктонибудь тестил ее в .Net4? Они ее оптимизировали вроде. Кто на ты с IL, потестите плиз.

Тестили. Тормозит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Генерация C# кода из Nemerle
От: Димчанский Литва http://dimchansky.github.io/
Дата: 25.05.11 09:50
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Кстати, ктонибудь тестил ее в .Net4? Они ее оптимизировали вроде. Кто на ты с IL, потестите плиз.


Я тут попробовал изобразить на F# тест хвостовой рекурсии (можно скачать проект с откомпиленным exe: TailRecursionTest.zip):
open System
open System.Diagnostics

let rec loop_rec n = 
    if n > 0L
    then help_tail_call (n-1L)
    else ()
and help_tail_call n =
    if n > 0L
    then loop_rec (n-1L)
    else ()
    
let loop_for n = 
    let mutable i = n
    while i > 0L do
        i <- i - 1L
    ()

let time s f =
    printfn "Starting '%s'..." s
    let sw = Stopwatch.StartNew()
    f()
    sw.Stop()
    printfn "Done in %f ms..." sw.Elapsed.TotalMilliseconds
    sw.Elapsed.TotalMilliseconds

let time_rec n = (fun () -> loop_rec n) |> time "rec"
let time_for n = (fun () -> loop_for n) |> time "for"

[<EntryPoint>]
let main (args : string[]) =
    if args.Length <> 1
        then failwith "Error: expected argument <loop count>"

    let n = Int64.Parse(args.[0])
    printfn "Ratio: %f" ((time_rec n) / (time_for n))
    printfn "Ratio: %f" ((time_rec n) / (time_for n))
        
    0


Рекурсию сделал через две рекурсивных функции, которые через tail call вызывают друг друга. Если делаешь в виде одной функции, то компилятор делает такой же цикл, как в loop_for.
Не знаю на сколько корректно. Но запустив программу (release build, any cpu) у себя на 64-битной системе получил:

> TailRecursionTest.exe 1000000000
Starting 'rec'...
Done in 1243.135100 ms...
Starting 'for'...
Done in 710.358100 ms...
Ratio: 1.750012
Starting 'rec'...
Done in 1242.459000 ms...
Starting 'for'...
Done in 711.537000 ms...
Ratio: 1.746162


Т.е. хвостовой вызов в 1.75 раза медленнее цикла. Для чистоты эксперимента нужно было бы наверное поправить IL код, чтобы loop_rec вызывала себя же.
Re[9]: Генерация C# кода из Nemerle
От: Ziaw Россия  
Дата: 25.05.11 09:50
Оценка:
Здравствуйте, Димчанский, Вы писали:

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


Д>Спасиб за пример, на досуге посмотрю.


Z>>А чем тебе не нравится идея компайл-тайм генерации? Nemerle под нее прекрасно заточен, а вот текстовую придется пилить самостоятельно. Изобретать разные пребилд скрипты. Форматировать этот текст. При этом никакого анализа окружения. Хотя, можно распарсить, конечно.


Д>Видишь, я еще не совсем в теме, поэтому не очень понимаю, что значит компайл-тайм генерация. Как это выглядит? Может пример есть?



Например так
В файле проекта заменяем:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
На
<Import Project="$(Nemerle)\Nemerle.MSBuild.targets" />

Пишем некий код:

[GenId]
class Test
{
  public static void Main()
  {
     var id = new Test().Id;
     Console.WriteLine("Compile time id = {0}", id);
  }
}


Создаем макрос в отдельной сборке:

[Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeTypedMembers, Nemerle.MacroTargets.Class)]
macro GenId(tb : TypeBuilder)
{
  tb.Define(<[decl: public Id : Guid = Guid.NewGuid() ]>)
}


Подключаем эту сборку к проекту csharp.

  <ItemGroup>
    <MacroProjectReference Include="..\path-to-macro-project.nproj">
      <Name>macro-project</Name>
      <Project>{macro-project GUID}</Project>
      <Private>True</Private>
    </MacroProjectReference>
  </ItemGroup>


Собираем. Весь код писался в браузере, вероятно где-то есть опечатки. Общий смысл, надеюсь, донес.
Re[2]: Генерация C# кода из Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.05.11 14:55
Оценка:
Здравствуйте, catbert, Вы писали:

C>Мне кажется, это не слишком сложно, но из-за некоторых особенностей языка (матч и возможно хвостовая рекурсия) сгенерированный код будет не таким эффективным, как в Немерле.


Эффективный код сгенерировать не проблема. Вот, легко читаемый сильно сложнее.

C>Влад говорил в видео
Автор: Ka3a4oK
Дата: 19.05.11
, что хотелось бы эту фичу реализовать.


Да. Но для Н2, В прочем, если кто-то возьмется за эту задачу в Н1, я буду только рад.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Генерация C# кода из Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.05.11 14:59
Оценка: 4 (1)
Здравствуйте, Димчанский, Вы писали:

Д>Скажите, насколько сложен такой финт ушами? Планируете ли?


Я планировал реализовать это в Н2. Ну, или в каком-то из промежуточных релизов.
Задача там не очень сложная, так что ее мог бы решить кто-то из комьюнити. На ней можно и язык подучить.

Кроме того эта же задача решается с другой стороны, со стороны декомпиляторов сборок. JetBrains dotPeek и ILSpy уже очень близки к тому чтобы полностью декомпилировать сборки немерла в C#. А это мало отличается от генерации кода по немерловым кишкам. Результат будет тот же — C#-код который можно скомпилировать компиляторами C#. Так что возможно, имеет смысл помочь разработчикам ILSpy-я и dotPeek-а. Первым можно просто присылать патчи исправляющие их ошибки. А вторым слать багрепорсты и просить их сделать поддержку немерла более качественной.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Генерация C# кода из Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.05.11 15:04
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Да, имеется ввиду генереация текста на C# из AST Nemerle. Насколько это сложно (по времени)?


Зависит от качества генерируемого кода которое хочется получить.

В принципе, если не заморачиваться на качество, то по типизированному AST можно довольно просто сгенерировать C#-код. Вот только качество этого код будет крайне низким. Там будет куча goto, вместо лямбд будут объекты, вместо ПМ будут страшные if-ы и т.п.

Если такой результат устроит, то могу рассказать как это дело добавить в компилятор.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.