« Named arguments | Main | Anonymous packages »
Tuesday
Apr192011

Yield!

The yield statement is a new feature in version 1.8.

A yield statement turns a function into a generator, which lazily generates a list of values. Each yield in the function returns a single value. The state of the generator function is preserved, so when the next value is requested, the execution of the generator function continues immediately after the yield.

An example (taken from MDC):

function simpleGenerator(){
  yield "first";
  yield "second";
  yield "third";
  for (var i = 0; i < 3; i++)
    yield i;
}

var g = simpleGenerator();
print(g.next()); // prints "first"
print(g.next()); // prints "second"
print(g.next()); // prints "third"
print(g.next()); // prints 0
print(g.next()); // prints 1
print(g.next()); // prints 2
print(g.next()); // StopIteration is thrown

The generator can also be used in for each-loops as if it was an ordinary array:

function numGenerator(){
  for (var i = 0; i < 3; i++)
    yield i;
}

for each (var x in numGenerator()) {
   console.log(x); // prints 0,1,2
}

(The for-loop catches the StopIteration internally in this case, as it just signals the end of the list.)

Generators are also known in languages like Python and C#. Mozilla have native support for generators, but no other browser I know of have.

Caveat

Generators are pretty cool, but there is one drawback. The compiler output is pretty inscrutable, since it requires somewhat convoluted code to support generator semantics in downlevel JavaScript. This is not a problem when the code runs, but may make it unpleasant to debug generator function produced by Mascara.

Generally Mascara aims to produce output code which is as clear and pretty as possible, but in the case of yield this is not really very clear.

Anyway, I would love feedback from Mascara users if you find 'yield' useful, and whether the generated code is acceptable.

PrintView Printer Friendly Version

EmailEmail Article to Friend