'function *' is not mandatory

Brendan Eich brendan at mozilla.com
Sat Aug 31 15:07:24 PDT 2013


Generators are a kind of factory function. When you call a generator, 
you get an iterator with a bit of extra protocol (.throw as well as .next).

No big deal, lots of API contracts are implemented by functions, you say 
-- why does this one deserve special head syntax. 'return' can be hard 
to spot, just as 'yield' could be hidden, in a large body -- and return 
of a certain-shaped object as part of an API contract could be even 
harder to discern.

In general, you have a point. Languages such as Scheme or Racket enable 
their users customize built-in syntax all the time to express contracts 
better, even with static syntactic checking using macros. Even 
macro-less languages may have decorators (CoffeeScript's syntax cleverly 
enables decorators "for free").

You might think of function* as decorator syntax. It's important, given 
the 'yield' backward compatibility issue, not to make the syntax too 
heavyweight. One character is as minimal as we can get.

But now I'm just shoring up the argument based on compatibility. You'll 
have to get Mark or someone else to help you understand their particular 
argument that the function head needs decoration to alert the reader to 
the possible (not required) presence of yield in the body.

Note also the empty-body basis case -- that's a good argument for 
function* independent from the backward-compatibility and 
good-for-readers arguments.

/be

> Yuichi Nishiwaki <mailto:yuichi.nishiwaki at gmail.com>
> August 31, 2013 2:12 PM
> I get the point. Indeed. Modes are a kind of magic...
>
> Regarding the secondary reason:
> I don't understand the "difference" well, could you explain in detail?
> You know, all other languages that are dynamically typed and have
> generators, such as python, lua, and even JavaScript 1.8 don't
> distinguish two kinds of the functions.
> I guess this directly means that there isn't something different as
> you said (because they all have more or less made successful).
> And in my personal view, yield is something that can be generalized
> together with return, like
>
> - return: discards the succeeding partial continuation there
> - yield: preserve the succeeding partial continuation there
>
> It is very clear in a sense, I believe. So my guess is that the
> strangeness yields have is a mater of getting used to, and that it is
> much more natural to treat two of them as a same thing.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Mark S. Miller <mailto:erights at google.com>
> August 31, 2013 1:33 PM
> On Sat, Aug 31, 2013 at 1:14 PM, Yuichi Nishiwaki 
> <yuichi.nishiwaki at gmail.com <mailto:yuichi.nishiwaki at gmail.com>> wrote:
>
>     OK, right. I understand my first propose does not work. :-|
>     So one more question is how about making '*' optional in strict mode?
>     (Should I separate the topic to another?)
>
>     2013/9/1 Brendan Eich <brendan at mozilla.com
>     <mailto:brendan at mozilla.com>>:
>     > Let's not go in circles -- the primary reason for function* is
>     because yield
>     > is not reserved in JS and is used by web content as a plain
>     identifier. It
>     > is a low-precedence unary prefix operator, so cannot be contextually
>     > reserved by a grammatical restriction as "module" can. It needs
>     opt-in
>     > syntax.
>     >
>     > Separately, some on TC39 want a flag on the function, in the
>     head syntax, to
>     > alert readers to the generator. That's a secondary reason,
>     independent and
>     > not as strong in my view.
>
>
> 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.
>
> Code is read much more than it is written -- at least code that matters.
>
>
>     >
>     > There's nothing to "get" or "not get" about backward
>     compatbility. It just
>     > "is". :-|
>     >
>     > /be
>     >
>     >> Yuichi Nishiwaki <mailto:yuichi.nishiwaki at gmail.com
>     <mailto:yuichi.nishiwaki at gmail.com>>
>     >> August 31, 2013 12:55 PM
>     >>
>     >> I can't get the point, why you need to know if the function is a
>     >> generator or not at a glance?
>     >>
>     >> 1. Forcing users to mark the function as a generator is only a
>     >> duplication. It basically doesn't have any meaning other than
>     >> double-checking, and fundamental risk for the unintentional
>     creation
>     >> is still not removed.
>     >> 2. Even if you know the function is a generator in early, you still
>     >> need to read the entire source code to get the information
>     about what
>     >> the generator yields and when it stops.
>     >> _______________________________________________
>     >> es-discuss mailing list
>     >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     >> https://mail.mozilla.org/listinfo/es-discuss
>     >>
>     >> Oliver Hunt <mailto:oliver at apple.com <mailto:oliver at apple.com>>
>     >> August 31, 2013 12:25 PM
>     >>
>     >> On Aug 31, 2013, at 12:15 PM, Yuichi
>     Nishiwaki<yuichi.nishiwaki at gmail.com
>     <mailto:yuichi.nishiwaki at gmail.com>>
>     >> wrote:
>     >>
>     >>> Hi all, I just found a post that the current generator syntax
>     >>> (function *) seems have decided in:
>     >>>
>     >>>
>     https://mail.mozilla.org/pipermail/es-discuss/2011-July/015799.html
>     >>>
>     >>> According to the post, the biggest reason the star syntax is
>     adopted
>     >>> for now is that you cannot write empty generators with star-less
>     >>> functions in a consistent simple way. But the situation has
>     changed,
>     >>> and in the current spec (rev 17) yield* is now capable of
>     taking any
>     >>> kind of iterator, so you can make empty generators just like
>     >>>
>     >>> ```js
>     >>> function * () {
>     >>>     yield * [];
>     >>> }
>     >>> ```
>     >>>
>     >>> This looks enough good and simple at least to me. And I wonder
>     if even
>     >>> now generators still need to be declared with 'star's. What
>     are the
>     >>> advantages of 'star'ed generators rather than 'star'-lesses?
>     If not
>     >>> exist, shouldn't it be removed (for the simplicity)?
>     >>>
>     >>
>     >> The reason for the * is substantially (IIRC) to make it
>     possible for an
>     >> engine
>     >> to help prevent developers from unintentionally creating a
>     generator
>     >> function,
>     >> and to make it possible for someone attempting to use a function to
>     >> identify immediately
>     >> whether it is a generator or a regular function.
>     >>
>     >> --Oliver
>     >>
>     >>> Thank you.
>     >>>
>     >>> --
>     >>> Yuichi Nishiwaki
>     >>> _______________________________________________
>     >>> es-discuss mailing list
>     >>> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     >>> https://mail.mozilla.org/listinfo/es-discuss
>     >>
>     >>
>     >> _______________________________________________
>     >> es-discuss mailing list
>     >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     >> https://mail.mozilla.org/listinfo/es-discuss
>     >>
>     >> Yuichi Nishiwaki <mailto:yuichi.nishiwaki at gmail.com
>     <mailto:yuichi.nishiwaki at gmail.com>>
>     >> August 31, 2013 12:15 PM
>     >>
>     >> Hi all, I just found a post that the current generator syntax
>     >> (function *) seems have decided in:
>     >>
>     >> https://mail.mozilla.org/pipermail/es-discuss/2011-July/015799.html
>     >>
>     >> According to the post, the biggest reason the star syntax is
>     adopted
>     >> for now is that you cannot write empty generators with star-less
>     >> functions in a consistent simple way. But the situation has
>     changed,
>     >> and in the current spec (rev 17) yield* is now capable of
>     taking any
>     >> kind of iterator, so you can make empty generators just like
>     >>
>     >> ```js
>     >> function * () {
>     >> yield * [];
>     >> }
>     >> ```
>     >>
>     >> This looks enough good and simple at least to me. And I wonder
>     if even
>     >> now generators still need to be declared with 'star's. What are the
>     >> advantages of 'star'ed generators rather than 'star'-lesses? If not
>     >> exist, shouldn't it be removed (for the simplicity)?
>     >>
>     >> Thank you.
>     >>
>     >> --
>     >> Yuichi Nishiwaki
>     >> _______________________________________________
>     >> es-discuss mailing list
>     >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     >> https://mail.mozilla.org/listinfo/es-discuss
>     >>
>     >
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>
> -- 
>     Cheers,
>     --MarkM
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> Yuichi Nishiwaki <mailto:yuichi.nishiwaki at gmail.com>
> August 31, 2013 1:14 PM
> OK, right. I understand my first propose does not work. :-|
> So one more question is how about making '*' optional in strict mode?
> (Should I separate the topic to another?)
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Brendan Eich <mailto:brendan at mozilla.com>
> August 31, 2013 12:58 PM
> Let's not go in circles -- the primary reason for function* is because 
> yield is not reserved in JS and is used by web content as a plain 
> identifier. It is a low-precedence unary prefix operator, so cannot be 
> contextually reserved by a grammatical restriction as "module" can. It 
> needs opt-in syntax.
>
> Separately, some on TC39 want a flag on the function, in the head 
> syntax, to alert readers to the generator. That's a secondary reason, 
> independent and not as strong in my view.
>
> There's nothing to "get" or "not get" about backward compatbility. It 
> just "is". :-|
>
> /be
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
> Yuichi Nishiwaki <mailto:yuichi.nishiwaki at gmail.com>
> August 31, 2013 12:55 PM
> I can't get the point, why you need to know if the function is a
> generator or not at a glance?
>
> 1. Forcing users to mark the function as a generator is only a
> duplication. It basically doesn't have any meaning other than
> double-checking, and fundamental risk for the unintentional creation
> is still not removed.
> 2. Even if you know the function is a generator in early, you still
> need to read the entire source code to get the information about what
> the generator yields and when it stops.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list