On May 16, 2019, at 2:43 PM, Alex Buckley <alex.buck...@oracle.com> wrote: > > If you're proposing to disallow a cast expression or a parenthesized > expression after a `yield` token, then I think that's not right. The parsing > of a `(` token has triggered potentially unbounded lookahead for some time > [1][2], and everything worked out, so I don't see why the language should > disallow any of John's examples: > > yield (String)("answer is "+x); > yield ("answer is "+x).trim(); > yield new String[]{ "answer is "+x }[0]; > yield Arrays.asList("answer is "+x).get(0); > yield false ? 0 : ("answer is "+x).trim();
Here's what's tricky: If there is a method called "yield" in scope, then one of those examples is a valid method call expression statement. import static MyFavYielder.yield; class Client extends MaybeHasYieldMethod { void m(int x) { var res = switch (x) { case 42 -> { yield ("answer is "+x).trim(); } default -> -1; }} Here's one way to slice it (very thin): The name "yield" is placed in scope in "->" blocks as if it were an inherited or imported static method. It acts like an arity-1 signature-poly method returning void. When "yield" is followed by a paren, an appeal to this method, and any other ambient methods named "yield" is made, and overloading and ambiguity analysis is done. If after all the special sig-poly method is matched, then the compiler edits the statement into a control flow construct. (This is circular: A control flow construct affects ambient DA/DU rules which might also indirectly affect types IIRC. So the type of the yield call maybe could circularly depend on the surrounding control flow.) If the built-in "yield" quasi-method conflicts with a real "yield" method that is in scope and matches, the we report an ambiguity to the user. (Ambiguity? Ya think??) The user has to fix it by using a fully qualified call to the intended yield or some similar dodge. If the yield statement is desired, at worst case the user makes a temporary variable, and yields *that*. This trickiness does tend to support a less ambiguous syntax, such as "yield -> x;" or (per Doug) "yield ^x;". — John P.S. I find "yield -> x" charming partly because the arrow seems to have additional possibilities: if (foo) { yield -> { var x = waitASec(); var y = OK; yield -> f(x, OK); }; } instead of: if (foo) { var x = waitASec(); var y = OK; yield -> f(x, OK); }