Здравствуйте, VladD2, Вы писали:
VD>Гы-гы. Ты наверно даже не понимаешь насколько ты ошибаешься. foreach в Немерле раз в 10 навороченее чем его аналог в C#. Он по полной программе поддерживает паттерн-матчинг.
Паттерн-матчинг сохранится. foreach ($x in $coll) $body будет преобразован в случае монады в $builder.ForEach ($coll, $x => $body). При желании эту кодо-генерацию можно будет переопределить. Меня сейчас больше for беспокоит. Чтобы свести к while нужен $builder.Zero (), которого может и не быть. Придется сводить к $builder.ForEach, а для этого придется создавать коллекцию (через ленивый stream).
Здравствуйте, dsorokin, Вы писали:
D>Здравствуйте, VladD2, Вы писали:
VD>>Гы-гы. Ты наверно даже не понимаешь насколько ты ошибаешься. foreach в Немерле раз в 10 навороченее чем его аналог в C#. Он по полной программе поддерживает паттерн-матчинг.
D>Паттерн-матчинг сохранится. foreach ($x in $coll) $body будет преобразован в случае монады в $builder.ForEach ($coll, $x => $body).
Погляди примеры использования foreach в этой статье
Потом foreach раскрывается в эффективную реализацию в зависимости от типа аргумента.
И одно замечание!
В твоем случае для описния лябды лучше использовать не синтаксис "$x => $body", а синтаксис "fun(x) { $body }".
Дело в том, что первый вариант (использованный тобой) — это тоже макрос. И я не гарантирую, что он учитывает все случае поддержки паттерн-матчинга которые реализованы в реальной лямбде. Это все же облегченный синтаксис.
D> При желании эту кодо-генерацию можно будет переопределить. Меня сейчас больше for беспокоит. Чтобы свести к while нужен $builder.Zero (), которого может и не быть. Придется сводить к $builder.ForEach, а для этого придется создавать коллекцию (через ленивый stream).
Ну, напиши ты ForEach через yield. Будет тебе ленивый ForEach.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Как определить принадлежность генерику?
От:
Аноним
Дата:
21.04.10 18:27
Оценка:
Здравствуйте, dsorokin, Вы писали:
D>Согласен. Как и с linq
В LINQ есть функции Select и SelectMany, которые отличаются подобным образом. Может, лучше в традициях линка оставить названия Yield и YieldMany?
Здравствуйте, dsorokin, Вы писали:
D>Здравствуйте, VladD2, Вы писали:
VD>>Гы-гы. Ты наверно даже не понимаешь насколько ты ошибаешься. foreach в Немерле раз в 10 навороченее чем его аналог в C#. Он по полной программе поддерживает паттерн-матчинг.
D>Паттерн-матчинг сохранится. foreach ($x in $coll) $body будет преобразован в случае монады в $builder.ForEach ($coll, $x => $body). При желании эту кодо-генерацию можно будет переопределить. Меня сейчас больше for беспокоит. Чтобы свести к while нужен $builder.Zero (), которого может и не быть. Придется сводить к $builder.ForEach, а для этого придется создавать коллекцию (через ленивый stream).
А нужен ли for? Я, например, последний раз я его использовал когда тестировали скорость пузырьковых сортировок.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, dsorokin, Вы писали:
D>>Согласен. Как и с linq
А>В LINQ есть функции Select и SelectMany, которые отличаются подобным образом. Может, лучше в традициях линка оставить названия Yield и YieldMany?
А может оставить Yield и YieldComp, но их будет заменять ключевое слово yield там где это возможно?
Здравствуйте, Аноним, Вы писали:
А>В LINQ есть функции Select и SelectMany, которые отличаются подобным образом. Может, лучше в традициях линка оставить названия Yield и YieldMany?
Здесь свои традиции: def!, do!, return!, yield!, use!. Но с восклицательным знаком возникла проблема разбора. Да и лично мне нравится теперь этот comp на конце: def/defcomp, do/docomp, return/returncomp, yield/yieldcomp, using/usingcomp. Но это можно поменять.
Здравствуйте, VladD2, Вы писали:
VD>Потом foreach раскрывается в эффективную реализацию в зависимости от типа аргумента.
В прошлый раз забыл о Zero. Здесь же монада:
foreach ($x in $coll) $body
=>
$builder.ForEach ($coll, fun ($(var : Name)) {
match ($(var : Name))
{
| $x => $body;
| _ => $builder.Zero ()
}
})
То есть добавляется еще одно требование. Либо без требования Zero, но и без мощного матчинга. Либо с требованием Zero, но и с развернутым матчингом. Дилемма. Может статься, что если определяется For, то и Zero как бы подразумевается сам собой (моноид). Надо поразмыслить.
Я же привел примеры. Посмотри внимательно второй пример. Там код получается сильно сложнее...
D>Несовсем понятно как, да и эффективнее сделать через ленивый поток:
Что там понимать то? Все элементарно:
public ForEachLazy[T](source : IEnumerable[T]) : IEnumerable[T]
{
foreach (x in source)
yeild x;
}
Далее применяем это дело к любому IEnumerable[T] и получаем ленивый вариант. Точнее он будет не совсем ленивым, так как при перезапуске будет возвращаться новый итератор. Но, как я понимаю, в данном случае разницы не будет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD> Я же привел примеры. Посмотри внимательно второй пример. Там код получается сильно сложнее...
Ну, да. Странность второго foreach сразу не разглядел. Подумаю над этим.
VD> Далее применяем это дело к любому IEnumerable[T] и получаем ленивый вариант. Точнее он будет не совсем ленивым, так как при перезапуске будет возвращаться новый итератор. Но, как я понимаю, в данном случае разницы не будет.
Гы. Зачем нужен ForEachLazy если есть уже source?.. Должно быть начало. И ленивый поток его дает. Я уже сделал for через foreach.
Кстати, необходимость Zero для foreach вытекает из простой вещи. Zero можно рассматривать как пустой цикл. Потому он должен быть.
Тут натолкнулся на неприятную вещь. Нельзя инстанцировать шаблон по типу void. Для монад это чертовски важно. Вопрос в том, будет ли это возможно в будущем, или это фича языка такая? Пока же создал поддельный тип ComputationVoid.
На сегодняшний момент состояние такое. Реализованы def, mutable, match, if, unless, when, while, do-while, foreach (с твоим замечанием — не умеет), for, repeat. Также монадические defcomp, return, returncomp, yield, yieldcomp и новые call, callcomp. Так я назвал аналоги do и do! из F#. Им как раз нужно инстанцирование по void. F# это умеет. Среди важных остались using, usingcomp и try. С первыми двумя придется повозиться.
Re[13]: Как определить принадлежность генерику?
От:
Аноним
Дата:
22.04.10 15:52
Оценка:
Здравствуйте, dsorokin, Вы писали:
D>То есть добавляется еще одно требование. Либо без требования Zero, но и без мощного матчинга. Либо с требованием Zero, но и с развернутым матчингом. Дилемма. Может статься, что если определяется For, то и Zero как бы подразумевается сам собой (моноид). Надо поразмыслить.
Здравствуйте, dsorokin, Вы писали:
D>Гы. Зачем нужен ForEachLazy если есть уже source?.. Должно быть начало. И ленивый поток его дает. Я уже сделал for через foreach.
Да, это я что-то ступил. Надо больше отдыхать .
Что же до твоего LazyStram, но во-первых напрягает его название. Это все же списко, а не поток.
А во-вторых в немерле есть макра для более элегантной реализации того же самого — макра Nemerle.lazy и тип LazyValue.
Вот погляди реализацию аналога твоего LazyStram: LazyList.n
D>Кстати, необходимость Zero для foreach вытекает из простой вещи. Zero можно рассматривать как пустой цикл. Потому он должен быть.
Ну, должен так должен.
D>Тут натолкнулся на неприятную вещь. Нельзя инстанцировать шаблон по типу void. Для монад это чертовски важно. Вопрос в том, будет ли это возможно в будущем, или это фича языка такая? Пока же создал поддельный тип ComputationVoid.
А нельзя просто перегрузкой обойтись? Во всех остальных случаях ею обходились.
D>На сегодняшний момент состояние такое. Реализованы def, mutable, match, if, unless, when, while, do-while, foreach (с твоим замечанием — не умеет), for, repeat. Также монадические defcomp, return, returncomp, yield, yieldcomp и новые call, callcomp. Так я назвал аналоги do и do! из F#. Им как раз нужно инстанцирование по void. F# это умеет. Среди важных остались using, usingcomp и try. С первыми двумя придется повозиться.
Поглядел... Примеров не хватает. Точнее они есть, но как-то они сумбурно организованы.
Хотелось бы чтобы можно было поглядеть на простые и понятные реализации и их применения.
Ну, и было бы здорово если бы про это все написать статейку. За одно и документация получилась бы!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Что же до твоего LazyStram, но во-первых напрягает его название. Это все же списко, а не поток. VD>А во-вторых в немерле есть макра для более элегантной реализации того же самого — макра Nemerle.lazy и тип LazyValue. VD>Вот погляди реализацию аналога твоего LazyStram: VD>LazyList.n
Нет, это нормальное название. Даже приставка Lazy лишняя. Такое название используется в хаскеле и SICP (Structure and Interpretation of Computer Programs). А так, твой пример — близнец, но такого класса нет в Nemerle.dll, и он не умеет превращаться в IEnumerable[T].
D>>Тут натолкнулся на неприятную вещь. Нельзя инстанцировать шаблон по типу void. Для монад это чертовски важно. Вопрос в том, будет ли это возможно в будущем, или это фича языка такая? Пока же создал поддельный тип ComputationVoid.
VD>А нельзя просто перегрузкой обойтись? Во всех остальных случаях ею обходились.
Увы, нельзя. Нужно создавать значения типа M[void], которые обозначают некие вычисления, которые во время своего выполнения производят некоторый побочный эффект. Это особенно будет заметно, если кто-нибудь создаст аналог async из F#.
VD>Поглядел... Примеров не хватает. Точнее они есть, но как-то они сумбурно организованы.
Да, сейчас примеры так себе для целей демонстрации. Я на них проверяю генерацию кода. Снимаю комментарий в файле CompMacro.n и смотрю, что там создается.
VD>Ну, и было бы здорово если бы про это все написать статейку. За одно и документация получилась бы!
Согласен. Постараюсь найти время.
Кстати, сейчас такая вещь. Синтаксис list/array/enumerable comprehension пересекается с синтаксисом в общем случае. Из-за этого важен порядок объявлений:
using Nemerle.ComputationExpressions;
using Nemerle.ComputationExpressions.Extensions;
Если две строки поменять местами, то парсер начинает ругаться. Знаю, что нехорошо. Может быть, поменять синтаксис для comprehension? Но хотелось бы сохранить простоту и единообразие.