Andy Wingo wrote:
Hi Brendan,

On Mon 29 Apr 2013 21:33, Brendan Eich<[email protected]>  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

JS1.7 and up in SpiderMonkey (and I expect Rhino; this was all from ES4):

./Darwin_DBG.OBJ/js
js> function foo() {
  try {
    yield 1;
  } finally {
    yield 2;
  }
}
js> o = foo()
({})
js> o.next()
1
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 }


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.

Yes, return in try runs finally, but that's independent of close and indeed of generators.

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".

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.

I think we should leave the close() method out of the 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

It's useful too, with no obvious alternative when you need it.

/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to