yield* desugaring

Andy Wingo wingo at igalia.com
Tue Apr 30 00:20:50 PDT 2013


Hi Brendan,

On Mon 29 Apr 2013 21:33, Brendan Eich <brendan at mozilla.com> writes:

> Andy Wingo wrote:
>> close() does not seem to have much value given that it isn't part of the
>> iterators specification, and one can do any needed action by doing a
>> throw() on the iterator and relying on the generator to have a finally
>> block if needed.
>
> But throwing has other unwanted effects, in general. First, you need to
> define a generator and give it a name. Then, close callers need to throw
> that exception. For this reason, Python defined a built-in exception,
> GeneratorExit.

In Python, the close() method has some interesting interactions with
finally:

    >>> def foo():
    ...   try:
    ...     yield 1
    ...   finally:
    ...     yield 2
    ... 
    >>> o = foo()
    >>> o
    <generator object foo at 0x7feb31184f00>
    >>> o.__next__()
    1
    >>> o.close()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: generator ignored GeneratorExit

Incidentally, close() is not the same as forcing a return:

    >>> def bar():
    ...   try:
    ...     return 1
    ...   finally:
    ...     yield 2
    ... 
    >>> bar().__next__()
    2

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.  GvR writes in the 2.5
release notes, when close() was introduced:

    The addition of the close() method has one side effect that isn't
    obvious. close() is called when a generator is garbage-collected, so
    this means the generator's code gets one last chance to run before
    the generator is destroyed. This last chance means that
    try...finally statements in generators can now be guaranteed to
    work; the finally clause will now always get a chance to run. The
    syntactic restriction that you couldn't mix yield statements with a
    try...finally suite has therefore been removed. This seems like a
    minor bit of language trivia, but using generators and try...finally
    is actually necessary in order to implement the with statement
    described by PEP 343.

    http://docs.python.org/release/2.5/whatsnew/pep-342.html

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.

I think we should leave the close() method out of the spec.

Andy


More information about the es-discuss mailing list