Generally, we want yield* to be as transparent as possible, so that if we have 
a Iterable Inner and a generator defined like:

function *wrapper() {
   yield *Inner();
}

any sequence of next/throw/return method calls on an iterator produced by 
wrapper will generate the same results as if  the same sequence of method calls 
had been directly applied to the Inner iterator instance that is wrapped.

And this generally works (or at least will after I finish fixing some bugs) if 
wrapper and Inner are both generators.  But here is the edge case where it 
appears impossible to achieve full transparency.

Generators always[*] have both a "return" and "throw" method and everything 
works transparently as expected.  However, if the iterator returned by Inner is 
not a generator object, it might not have a "throw" method but still have a 
"return" method. Normally a "throw" to such a wrapper iterator would be 
forwarded by yield* to the inner iterator's throw method, presumably triggering 
any "finalization" processing needed by the inner iterator.   However, yield* 
can't forward the the throw to a non-existent inner "throw" method. But the 
existence of a "return" method is a strong hint that the inner iterator may 
have some "finalization" it should be given an opportunity to perform. 

It seems like, there are two plausible semantics for this case, each with an 
undesirable characteristic:

1) yield* doesn't invoke anything on the inner iterator in this situation.  
Transparency is preserved, but the inner iterator may have "finalization" 
processing that never gets executed
2) yield* invokes "return" on the inner iterator in this situation.  Inner 
iterator gets a chance to run its "finalization" processing.  But full 
transparency is lost as a method is invoked on the inner iterator that that 
would not have been invoked with the wrapper wasn't sitting in the middle.

(Note that wrapper already isn't truly transparent, because it is exposing a 
"throw" method that doesn't exist on the iterator iterator.  It's possible, 
that the  visibility of the "throw" method is what caused the consumer to 
invoke it, rather than invoking the "return" method.)

So, opinions on which of these alternatives is better? Are there any others?

Allen

[*] this situation actually can occur when Inner is also a generator, but it 
requires over-riding the 'throw' method for that generator's instance with 
undefined.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to