On Nov 27, 2012, at 12:45 AM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> There would be another way to accomplish supporting generator return values 
>> that doesn't require dynamically constructing new StopIteration instances 
>> and avoids all Realm issues:  Capture the return value in the generator 
>> instance when it enters the "closed" state and then throw the single 
>> immutable StopIteration object (could be a Symbol).  A client of the 
>> generator instance that catches StopIteration and expects a return value can 
>> directly query the generator instance (via a property access) to get that 
>> return value.  It accomplishes the same thing but doesn't require multiple 
>> StopIteration instances, an extract allocation on generator returns, a call 
>> to isStopIteration to test, etc.
> ...
> Not much of a change, but something crucial is lost. The try could possibly 
> .send or .next another task's generator-iterator (task.thread), possibly 
> under pump if it immediately dispatched (it doesn't, but suppose it did). 
> You're programming by side effects here, requiring the catcher of e to know 
> that task.thread.value is the mutable pigeon-hole to inspect.
> 
> This smells pretty bad compared to the PEP-380 style alternative, which 
> cleanly localizes the result to e.value.
> 
It's always bothered me that there is do direct linkage between between a 
generator instance that might throw a StopIteration and the actual 
StopIteration value that is thrown.  In particular, if you catch StopIteration 
you don't know which generator instance may have thrown it.  I don't think this 
is an issue for for-of invoked generator instances but it might be an issue of 
mainly invoked generator instances such as those in a task scheduler.  There is 
nothing that prevents somebody invoking next an a generator/iterator without 
wrapping it with a try-catch.

So here is a new idea.  Why not throw the iterator/generator instance it self 
as the "stop iteration" exception instance.  For example:

function *myGenerator() {
    yield 1;
    return 2;
}

myGen = myGenerator();
try {
   while (true) doSomething( myGen.next()
}  catch (e)  {
   if (e===myGen()) doLast(myGen.returnValue);
   else throw e;
}

Someone calling a generator next method, by definition a a reference to the 
generator so has it available to look for as an exception object.

Allen
   






> /be
> 

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

Reply via email to