Project Lambda: Java Language Specification draft

Stephen Colebourne scolebourne at joda.org
Sat Jan 23 08:43:27 PST 2010


2010/1/22 Alex Buckley <Alex.Buckley at sun.com>:
> [15.8.7 Lambda instance invocation]
>  #()(42)!()  // Evaluates to the value 42.
>
>  #int() fortyTwo = #()(42);
>  assert fortyTwo!() == 42;
>
>  #int(int) doubler = #(int x)(x + x);
>  assert doubler!(fortyTwo!()) == 84;

I find the ! invocation pretty darn ugly I'm afraid. I can't help
reading "not". The symbol also blends into the brackets visually.

 assert doubler.invoke(fortyTwo.invoke()) == 84;

The simple approach is more verbose and explanatory, which is quite in
the style of Java.

> Shadowing already makes an expression's meaning be context-dependent,
> but shadowing is both rare and easy to detect; obscuring between a
> method and a function-typed variable would be more common and harder
> to detect. Harder because it involves reasoning about inheritance: of
> methods if a function-typed variable seems to be invoked, and of
> function-typed fields if a method seems to be invoked.
+1

> Specifying that every function type has an invoke() method is
> plausible but concision is moderately important for lambdas, so it's
> not my preferred option.

Concision must not cause confusion. The closest parallel to invoking a
lambda today, is invoking a reflection Method. It seems perfectly
reasonable to use that parallel, especially given the meaning given to
"return", and the mental model similarity to an inner class.

> [5.1.14 Lambda Conversion]
> A SAM (Single Abstract Method) type is a top-level class or interface
> type with abstract member methods......
> If a SAM type is a class type, then it must be declared abstract and
> have a no-args constructor.

I don't think its a good idea supporting SAM classes. I'd prefer only
SAM interfaces. While this is an extra restriction, it allows greater
freedom in implementations and doesn't greatly constrain usage of
lambdas. It also removes a boatload of complexity from your spec as to
the meaning of inherited methods and variables from the SAM
superclass(es). With SAM interfaces, you only have static constants to
deal with, and they can be accessed using the full
SAMInterfaceType.CONSTANT notation (making the SAM interface
completely independent of the lambda). This also separates lambdas
from inner classes in developers minds, which is necessary to support
the correct (useful) semantics for "this" (ie the enclosing lexical
object).

I'm guessing that SAM classes are motivated by some specific use
cases, perhaps in the JDK. I'd strongly suggest that those use cases
should have API changes in parallel to lambdas instead of permitting
SAM classes.

Looking forward to feedback on the points raised by everyone.
Stephen


More information about the lambda-dev mailing list