On Apr 25, 2014, at 4:53 AM, Kevin Smith wrote:

> It seems to me that generators are not the best mechanism to express resource 
> management ("abstract over expensive resources") because the programmer of 
> the generator can never guarantee that the consumer will exhaust it.  If we 
> want direct language support for resource management, then a proposal should 
> be crafted to add that as a distinct feature.
> 


We routinely make use case based argument to justify new features. But once we 
have a feature, we can't expect it to be used only for the original use cases 
that motivated its inclusion. In integrating a feature we need to look at a 
feature's actual semantics and how those semantics interact with the semantic 
of existing and proposed features. At that point, we shouldn't be thinking 
about whether a particular use case is "good" or "bad" . It is only the 
semantic interactions that we should consider.

In this case we have try-finally statements as an existing feature.  The 
semantics of this feature is a bounded execution scope with a cleanup action on 
completion. This feature is widely used and has always been internally 
consistent and reliable, expect for catastrophic external failure or 
intervention (ie, externally imposed process termination, power failure, etc).  
People use it for all sorts of things, including bounded resource management. 

We then added a new feature, generators, which in some cases changes the 
semantics of try-catch.  No longer is the execution of the try block bounded in 
a manner that guarantees that the finally block will execute after completion 
of the try block.  That seems like a significant semantic change to try-finally 
and a usage hazard that we should be concerned about. 

Support for @@return and its use by for-of  would help to restore the 
try-finally invariants for what is likely to be the most commonly seen semantic 
feature composition (I'm not taking about use cases here) of for-of, 
generators, and try-finally.  That's an imperfect solution because when for-of 
isn't used it places a burden on the JS programmer to do manual work to ensure 
the try-finally invariant of a (possibly) generator invocation.  However, it 
seems like a significant improvement over the currently spec. behavior which 
just flat-out breaks a generator's try-finally invariant for any abrupt 
termination of a for-of loop. 

The @@return solution still seems like a good compromise design.  However, 
there is another way to attack this problem.

The fundamental problem is that any generator that looks anything like this:
   function *f() {
        try {yield} finally {postcondition()}
   }

has an unreliable try-finally block.  Whatever the programmer things is going 
to happen, may not actually happen.  The problem is the yield (a new feature 
that is corrupting the legacy semantics of try-finally). 

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.

Allen

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

Reply via email to