Call for bikeshed -- break replacement in expression switch
John Rose
john.r.rose at oracle.com
Fri May 17 01:15:36 UTC 2019
On May 16, 2019, at 2:43 PM, Alex Buckley <alex.buckley at 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);
}
More information about the amber-spec-experts
mailing list