Выбор синтаксиса для выражений, генерирующих список [закрыт]
Вопрос
C # имеет функции генератора, которые имеют синтаксис, такой как:
IEnumerable<int> GetNats(int max)
{
for (int i=0; i < max; ++i)
yield return i;
}
Интересующая меня особенность моего языка программирования (простое объектно-ориентированное программирование, подобное Java, Scala, ActionScript и C #) - это выражения-генераторы. Это по сути синтаксический сахар для функций генератора. Р>
Мой текущий любимый кандидат - следующий синтаксис:
IEnumerable<int> nats =
witheach (i in range(0, 42))
yield i * 2;
Выражение range (0, 42)
- это встроенная функция генератора.
Итак, мой вопрос в том, какой синтаксис вы бы предпочли видеть для выражений генератора на языке типов C # / Java / Scala / ActionScript и почему? Р>
Некоторые факторы, которые могут влиять на ответы, заключаются в том, что, например, Scala и ActionScript, типы в моем языке объявляются после типа. Например:
var myVar : SomeType = initialValue;
Также анонимные функции выглядят так:
var myFunc = function(int x) {
return x + 1;
}
Кроме того, остальная часть моего языкового синтаксиса напоминает Java или C #. Мой язык имеет оператор foreach
, который очень похож на C #. Р>
Решение
Существует также подход Python - нет специального синтаксиса для генераторов; наличие «доходности»; заявление все, что нужно Могут использоваться любые операторы, которые принимают блок, хотя я ожидаю найти только циклы, используемые на практике:
IEnumerable<int> nats =
for (i in range(0,42))
yield i*2
String phrase = "I want to buy some cheese.";
IEnumerable<int> substrs =
for (i in 0 .. phrase.length)
for (j in i .. phrase.length+1)
yield phrase[i..j]
Здесь я предполагаю, что правильная конечная точка не включена в диапазон.
Честно говоря, когда я увидел это в Python, мне пришлось задуматься: «Сколько это будет стоить?»
Другие советы
Посмотрите, что делает F #. Вы можете сделать
seq { seq-expr } // IEnumerable<T>, a.k.a. seq<T>
[ seq-expr ] // list<T>
[| seq-expr |] // array<T>
где seq-expr - это форма, которая включает в себя большинство языковых конструкций вместе с «yield». Так, например Вы можете написать
seq {
for i in 0..9 do
for j in someColl do
if i <> j then
yield i*j
}
Компилятор F # переводит этот код в реализацию конечного автомата IEnumerable (как C # делает для блоков итераторов). Р>
Мне нравится этот синтаксис, потому что это означает, например, вы можете написать точно такой же код, который вы бы написали, чтобы «делать императивные вещи сейчас», например
for i in 0..9 do
for j in someColl do
if i <> j then
printfn "%d" i*j
но оберните этот код в seq {} и используйте «yield», и вместо этого код становится ленивым IEnumerable.
IEnumerable nats = 0...42 or for generators IEnumerable nats = yield 0...42