'function *' is not mandatory

Claus Reinke claus.reinke at talk21.com
Sat Aug 31 14:08:26 PDT 2013


> I am one of those on TC39 that want the visible flag. Since, in my view,
> the only non-mistaken need to preserve sloppy mode is as an ES3
> compatibility mode and ES3 has no generators, I consider this flagging
> issue to be the important one. Yes, you have to read the function to know
> *what* it generates. But even before you've figured that out, your whole
> effort to read the function is different once you know you're reading a
> generator function. Better to know it early.

But that is a *semantic* property - you can't force it into *syntax*.

Consider this code:

    // run with node --harmony
    function* gen() { yield 1 }
    function f(g) { return g() }
    console.log( f(gen).next() ); // { value: 1, done: false }

You can't see by looking at 'f' that it can return an iterator. And 'f's
parameter and return value could even vary dynamically.

I could imagine a type system for this, which would be nice (just as it 
would be nice to have a type system telling you whether a callback-taking 
function uses the callback async, sync, or both). Then your IDE could tell
you (an approximation of) what you're dealing with, providing verified
API documentation. But I don't see how to do that with syntactic tools only.

> Code is read much more than it is written -- at least code that matters.

For this reason, I would still suggest to separate generators from 'function' -
there is nothing function-specific about generators (apart from generator
implementations using stack frames, perhaps), so I find it confusing to
mix up these two concepts. It also keeps us from using arrow functions 
freely with generators.

I did suggest using something like 'do* { yield 1 }' as generator syntax
(ie, 'do*{}' would be an expression denoting an iterable, and 'yield' could
only appear in 'do*{}'). It still has the syntactic flag, but it separates functions 
and generators. We could then recombine the two as needed, without 
complicating the 'function'-related specification machinery:

    let gen = v => do* { yield v };
    gen(1).next()    // { value: 1, done: false }

Claus
 


More information about the es-discuss mailing list