yield* desugaring

Andy Wingo wingo at igalia.com
Tue Apr 30 01:18:04 PDT 2013


Hi Brendan,

On Tue 30 Apr 2013 09:47, Brendan Eich <brendan at mozilla.com> writes:

> js> o.close()
> typein:5:0 TypeError: yield from closing generator function foo() {
> typein:5:0   try {
> typein:5:0     yield 1;
> typein:5:0   } finally {
> typein:5:0     yield 2;
> typein:5:0   }
> typein:5:0 }

For the record, this behavior is not specified in harmony:generators.
Also it seems to me to be an unnecessary restriction that originated in
Python's desire to always run the finally blocks -- not a goal of ES6.

>> Incidentally, close() is not the same as forcing a return:
>>
>>      >>>  def bar():
>>      ...   try:
>>      ...     return 1
>>      ...   finally:
>>      ...     yield 2
>>      ...
>>      >>>  bar().__next__()
>>      2
>
> That does not show close in action, though. The generator-iterator runs
> once there, yielding 2.

Sure.  I just mean to say that close introduces some mental
complication.  "A yield expression can produce a value or throw an
expression.  Except when close() is called, in which case it's like a
return.  But not quite like a return."  The spec would be better without
the last two sentences IMO.

>> Python's use case is also different because it specifies that when the
>> generator object is finalized, the close() method gets called --
>> certainly something we don't want to do for ES6.
>
> Quite. Long-ago es4-discuss threads covered all of this.
>
> https://mail.mozilla.org/pipermail/es-discuss/2006-December/
> https://mail.mozilla.org/pipermail/es-discuss/2007-January/
>
> Look for "Immediate closing of iterators".

If a generator runs to completion, there is no need to close it -- the
operation is a no-operation.

A bug mentioned in that discussion:

  https://bugzilla.mozilla.org/show_bug.cgi?id=349326

seems to suggest that you expect close() to be called when the generator
is collected, which again is not an ES6 thing.

>> ES6 certainly won't provide a guarantee that finally blocks will run, so
>> it seems to me that the main reason for close() is gone.
>
> The JS1.7 prototype for ES4 ran close automatically only from for-in
> (which evolved into ES6's for-of). That's still on the table.

Though yield* is currently specified to call close(), I don't believe
that close() is in the for-of spec.

> See above. Automating generator close from for-of is straightforward:
>
> js> function foo() {
>   try {
>     yield 1;
>   } finally {
>     print("glorp");
>   }
> }
> js> for (let x of foo()) print(x)
> 1
> glorp

This doesn't require close() at all to work!  Did you have another
example in mind?

It really seems to me that this is an interface that was made because of
Python's "always-run-the-finally-block" thing, which ES6 doesn't have.
Because we don't have that need, it does not seem useful to me.

Andy


More information about the es-discuss mailing list