> On 6 Apr 2019, at 21:17, Remi Forax <[email protected]> wrote:
>
> Currently this code doesn't compile
> IntConsumer c = x -> switch(x) { default -> System.out.println(x); };
>
> I believe it should because this is the basic pattern for supporting the
> actor model,
> you consume a message and do a side effect* depending on the type of the
> message,
> translated in Java, you want a lambda that takes a message as parameter,
> calls a switch to do the pattern matching and return void.
I understand, although this is actually to do with the way lambda expressions
are typed, rather than the switch expression. In JLS 15.27.3 "Type of a Lambda
Expression”, there is a special case:
• If the function type's result is void, the lambda body is either a
statement expression (§14.8) or a void-compatible block.
Which means that the following code typechecks:
IntConsumer ic = x -> System.out.println(x);
but it breaks as soon as we nest the statement expression, e.g.
IntConsumer ic2 = x -> true ? System.out.println(x) : System.out.println(x); //
Compilation error: target-type for conditional expression cannot be void
This is what is happening in your example. So to deal with this we’d either
have to make typechecking of lambdas smarter - either by replacing the typing
rule for lambdas above with something more compositional, or by making void a
first-class type, or we could perhaps add a pattern-matching form of lambda,
which has a void-aware typing rule. I’m not sure about any of these options for
now.
Cheers,
Gavin