Вопрос

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top