Proposal to simplify Generators impact

# Lucio Tato (12 years ago)

It's really needed to make js syntax more complex in order to implement generators? It's function* really needed? can you just expose "Generator" as a core function? can "yield" be a function-call-like-construct instead of a new language construction?

function fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield(curr);
    }}

Generators can be iterated over in loops:

for (n of new Generator(fibonacci) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);}

Generators are iterators:

let seq = new Generator(fibonacci);print(seq.next()); //
1print(seq.next()); // 2print(seq.next()); // 3print(seq.next()); //
5print(seq.next()); // 8

Advantages: No new syntax, no "function*" (Cognitive dissonance, every good C programmer can't stop reading function* as "function pointer"). No "yield" new construction. No added complexity to the language syntax.

By not adding new elements and complexity to the language, you're keeping it consistent.

By using "new Generator(fn)" to create a Object-Generator, you can also expose a "done" property and other useful info in a standard way.

Note: why yield syntax should be like a function call: In actual implementations (V8 --harmony) "yield" will "return" the value passed in the call to ".next"

function giveNext(){ //generator
  let actual = 10;
  while (actual<100){
       skip = yield(actual);
       actual = actual + skip || 5;
   };};
let seq = new Generator(giveNext);print(seq.next()); //
10print(seq.next()); // 15print(seq.next(20)); // 35print(seq.next());
*// 40****let* seq = new Generator(giveNext);
while (!seq.done)
   print(seq.next());
# Rick Waldron (12 years ago)

On Sat, Oct 26, 2013 at 1:01 PM, Lucio Tato <luciotato at gmail.com> wrote:

It's really needed to make js syntax more complex in order to implement generators? It's function* really needed?

Yes, because yield is only reserved in strict mode code, which means this is valid today:

function g() { yield = 1; return yield; }

Since the starred generator function is a new syntactic form, there is no existing code that it can possibly break by making yield a keyword.

can you just expose "Generator" as a core function? can "yield" be a function-call-like-construct instead of a new language construction?

No, because there may already be code that defines a function called yield, which would be broken if suddenly yield was a special language-owned function. Consider this:

// your code defines this...
function yield() { return Number.MAX_VALUE; }

// you then include my library, which exposes this fibonacci():
function fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield(curr);
    }}

What does yield() do? It returns Number.MAX_VALUE every time.

# Lucio Tato (12 years ago)

Rick: I understand. But it is always a trade-off.

If the reason to introduce a new construct is because there may already be code that defines a function called yield, it seems to me as a bad trade-off. (advantages vs disadvantages)

In your example...

function yield() {... <- will raise a parsing error.

Anyway, there are other ways to solve that. You can put the asterisk in "yield" instead of the important "function". It's a lot less confusing.

function fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield*(curr);
    }
}
# Axel Rauschmayer (12 years ago)

Another reason: you can’t have empty generators without marking them in some manner.

# Till Schneidereit (12 years ago)

On Sun, Oct 27, 2013 at 1:59 AM, Lucio Tato <luciotato at gmail.com> wrote:

    yield*(curr);

Note that, in difference to function* foo, that is valid ES5. In fact, I bet there is real code along the lines of yield*(time - offset) out there.

# Brendan Eich (12 years ago)

Yup.

Look (Licio), we've been over this many times, recorded here in es-discuss (directly in posts and in TC39 meeting notes). We are not adding generator syntax lightly. It is necessary to preserve backward compatibility.

# Oliver Hunt (12 years ago)

On Oct 26, 2013, at 4:59 PM, Lucio Tato <luciotato at gmail.com> wrote:

Rick: I understand. But it is always a trade-off.

If the reason to introduce a new construct is because there may already be code that defines a function called yield, it seems to me as a bad trade-off. (advantages vs disadvantages)

In your example...

function yield() {... <- will raise a parsing error.

You can’t make yield a reserved word — which is what you’re asking for here. This isn’t a matter of whether or not you use generators, it’s a matter of whether other code in the same environment ever uses a property named yield. All of the options necessarily require breaking yield in existing code

Anyway, there are other ways to solve that. You can put the asterisk in "yield" instead of the important "function". It's a lot less confusing.

function fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield*(curr);

This already parses a (yield)*(curr)

Please stop trying to get rid of the *, there isn’t any other viable option, and this has been covered ad nauseum on es-discuss

# Lucio Tato (12 years ago)

OK. Now I've read the email threads (didn't found them the first time). Now I understand why. Thanks.