Yield as contextual keyword (was: Call for bikeshed -- break replacement in expression switch)

Guy Steele guy.steele at oracle.com
Mon May 20 20:10:00 UTC 2019


Okay, with this more detailed explanation and understanding, I am back in the `yield` camp.  But I’m glad to have explored that side path just a bit.

> On May 20, 2019, at 3:51 PM, Brian Goetz <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>> wrote:
> 
> Clarification on Option (B): the rational thing to do is probably not to restrict this behavior to switchy blocks, because there are other kinds of statement contexts that will be embedded in switchy blocks, such as:
> 
>     case L -> {
>         if (cond) 
>             yield e;
>     }
> 
> And surely we want to treat this as a yield (in fact, the inability to do this in loops was one of the reasons we rejected `break` in the first place.). Which means we always parse `yield <expr>` as a yield statement, and if someone happens to call an _unqualified_ unary method called yield, they get an error (with a helpful suggestion that they might want to try a qualified yield.). 
> 
> So, to quantify the cost of a conditional keyword here: invocations of the form yield(e) will be parsed as statements, though qualified invocations (this.yield(e), Thread.yield(e), etc) will be parsed as method invocations.  The cost-benefit analysis rests on the assumption that this will bite exceedingly rarely, and when it does, the workaround will be clear and easy. 
> 
> 
>> OPTION B: DISALLOW UNQUALIFIED INVOCATION
>> -----------------------------------------
>> 
>> From a parser perspective, this is similarly straightforward: inside a switchy block, give the rule `yield <expr>` a higher priority than method invocation.  The compiler can warn on this ambiguity, if we like.  
>> 
>> From a user perspective, users wanting to invoke yield() methods inside switchy blocks will need to qualify the receiver (Foo.yield(), this.yield(), etc). 
>> 
>> The cost is that a statement “yield (e)” parses to different things in different contexts; in a switchy block, it is a yield statement, the rest of the time, it is a method invocation.  
>> 
>> I think this is much less likely to cause user distress than Option A, because it is rare that there is an unqualified yield(x) method in scope.  (And, given every yield() method I can think of, you’d likely never call one from a switchy block anyway, as they are side-effectful and blocking.). And in the case of collision, there is a clear workaround if the user really wanted a method invocation, and the compiler can deliver a warning when there is actual ambiguity.  
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20190520/6a914821/attachment-0001.html>


More information about the amber-spec-experts mailing list