Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of an asterisk (*) in ES6 generator functions

Can someone explain to me: why are generator functions in ES6 marked by asterisk symbol?

For example, instead of:

function *someGenerator() {     yield 1;     yield 2;     yield 3; } 

we could write:

function someGenerator() {     yield 1;     yield 2;     yield 3; } 

or even:

var someGenerator = () => {     yield 1;     yield 2;     yield 3; }  var someObject = {      someGenerator() {         yield 1;         yield 2;         yield 3;     } }             

The JS compiler can detect that someGenerator contains yield operator at the parse time and make a generator from this function.

Why is detection of yield existence not enough?

like image 383
alexpods Avatar asked Jan 05 '15 10:01

alexpods


People also ask

What does the asterisk do in JavaScript?

The function* declaration ( function keyword followed by an asterisk) defines a generator function, which returns a Generator object.

What is a generator function in ES6?

The ES6 generator is a new type of function that can be paused in the middle or many times in the middle and resumed later. In the standard function, control remains with the called function until it returns, but the generator function in ES6 allows the caller function to control the execution of a called function.

What is a generator function in JavaScript?

A generator is a process that can be paused and resumed and can yield multiple values. A generator in JavaScript consists of a generator function, which returns an iterable Generator object.

What does => mean in ES6?

It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.


2 Answers

The three reasons were:

  1. Readability. A generator is quite different from a function, and the difference should be immediately visible (that is, without examining the whole implementation in search for a yield).

  2. Generality. It should be naturally possible to write generators that do not yield, and only return directly. Moreover, commenting out part of the body (e.g. for debugging) should not silently change whether something is a generator.

  3. Compatibility. Only strict mode reserved 'yield' as a keyword, but it was made a goal for ES6 that all new features are also available in sloppy mode (an unfortunate decision IMHO, but nevertheless). Moreover, even in strict mode there are many parsing subtleties around 'yield'; for example, consider default arguments:

    function* g(a = yield(2)) { 'use strict' } 

    Without the *, the parser could only decide how to parse the yield after it has seen the body of the function. That is, you would need infinite look-ahead, or back-tracking, or other hacky techniques to deal with this.

I should note that (1) and (2) are already reason enough.

(Full disclosure: I am a member of the EcmaScript committee.)

like image 123
Andreas Rossberg Avatar answered Oct 23 '22 08:10

Andreas Rossberg


Empty generators (with no body) are not disallowed; so should unStarredFunc() follow generator semantics or not?

For compatibility reasons:

function yield(x) { return x };  function a() {      yield (4+1); }; 

this is syntactically correct but calling .next() would result in an error whereas adding an asterisk to explicitly define a generator would cause .next().value === 5

detect that someGenerator contains yield operator at parse time

Some constructs cannot be resolved at parse time:

function someGenerator(i) {      if (glob)          return 4;      else          yield* anotherGen(i); } 

And of course its simpler to see immediately from the function* definition that its a generator without needing to dig into its source to look for yields.

like image 21
Alex K. Avatar answered Oct 23 '22 09:10

Alex K.