void handling in expression lambdas and lambda conversion

Neal Gafter neal at gafter.com
Wed Jan 13 10:21:40 PST 2010

On Wed, Jan 13, 2010 at 1:24 AM, Peter Levart <peter.levart at marand.si> wrote:
> I have two questions about void handling.
> Currently, as specified by CfJ 0.6a, expression lambda form takes an expression:
> # ( FormalParameters opt ) Expression
> Since valid "Expression" as defined by JLS allways denotes a result value, such lambdas can only be assigned to function types that specify a return type that is assignment compatible with the lambda's expression.

>From JLS3 15.1: "An expression denotes nothing if and only if it is a
method invocation (§15.12) that invokes a method that does not return
a value, that is, a method declared void (§8.4)."

Clearly, an expression may denote nothing.  It goes on to say: "Such
an expression can be used only as an expression statement (§14.8),
because every other context in which an expression can appear requires
the expression to denote something."

CfJ 0.6a currently does not have such a requirement, so either the
requirement would be added (the expression of a lambda expression must
denote a value) or this sentence in 15.1 should be relaxed.  I don't
have strong feelings one way or another.

> My first question is: Would these be considered valid assigments:
> #void() lambda1 = #() (Void)null;

The lambda conversion as written doesn't allow this, but I think
that's a bug in the spec.  0.6b depends on it working.  I've updated
the 0.6a spec and added your name to the acknowledgments.

> #void() lambda2 = #() 1;

Not currently.  Can you explain why it would be a good idea to allow this?

> The other question is: Would it be possible to relax constraints for the expression specified in expression lambda to allow a method invocation of a void method?

Sure, it would be possible.  What is the benefit?

> I know that "Method References" are even a more compact syntax, but as specified, are not powerfull enough for specifying this:
> int a = 1;
> #void(int) lambda = #(int b) method(a, b);

True, but you could write this, which is arguably more clear:

#void(int) lambda = #(int b) { method(a, b); }


More information about the closures-dev mailing list