Proposal to simplify Generators impact
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.
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);
}
}
Another reason: you can’t have empty generators without marking them in some manner.
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.
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
OK. Now I've read the email threads (didn't found them the first time). Now I understand why. Thanks.
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());