On Apr 25, 2014, at 9:10 AM, Allen Wirfs-Brock <al...@wirfs-brock.com> wrote:
> People will write code like this if we allow it. But we don't have to allow. > We can preserve the semantics of try-finally by simply making the occurrence > of the 'yield' operator syntactically illegal within the try block of a > try-finally. > > We could do this. The parameterized grammar notation we now use in the ES6 > spec. makes it fairly easy to specify that you can't write code like the > above. > > Should we do it? I'm not sure. I still think that @@return is a reasonable > but imperfect alternative that allows generator authors to continue to use > what many think is a useful feature. Outlawing 'yield' in a try-finally is a > almost perfect solution to the semantic impedance mismatch between > try-finally and generators. But we also loose some expressiveness. Promised you a reply to this one, sorry -- I'm not comfortable with this restriction. It violates my Schemer's intuition [1]. In particular it creates a number of refactoring hazards: (1) add some try/finally code around code to deal with something other than the yield it contains; (2) refactor some try/finally code outside of a generator into a generator. Here's my perspective: - Iterators should generally be short-lived. - We should optimize the language design around ensuring that they will generally be exhausted. - In most use cases users won't even touch an iterator directly; it'll just be created and passed directly into the for-of loop (or a combinator, which itself will often be implemented with a generator function that consumes the wrapped iterator in a for-of loop). - The fact that iterators are first-class objects means it's *possible* to prevent an iterator from being terminated, but termination is never an absolute guarantee in Turing-complete languages to begin with. So the design I favor is: - Generators always have a .return() method. - All three of .next, .throw, and .return should take an optional argument. - All three of .next, .throw, and .return should return an iteration record ({ value: any, done: boolean }). - The semantics of for-of (as well as any combinators we specify post-ES6) should call .return() on the underlying iterator iff there's an abrupt completion. If the iterator terminates itself the loop should not force a .return() -- this isn't just a performance compromise, it avoids calling .return() on a closed generator. - If the implicit .return() of a for-of loop produces done: false, that indicates the iterator refused to be terminated, and the for-of loop should throw an exception. (This exception should throw from outside the loop, so no catch blocks inside the loop should catch it.) Dave [1] "Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary." _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss