Lambda Conversion Considered Harmful?
Reinier Zwitserloot
reinier at zwitserloot.com
Fri Feb 19 15:09:59 PST 2010
If the #Comparator(String a, String b)... syntax survives, may I suggest
putting the type name _before_ the hash? This opens the door to implementing
non-SAMs with the closure syntax. For example:
WindowAdapter#windowClosing(WindowEvent e) {}
where the method name (the identifier between hash and open paren) is
optional only if the Type name (to the left of the hash) resolves to a SAM
type.
The reason for setting up the syntax this way is mostly the same reason SAM
conversion is being looked at in the first place - to be useful to existing
libraries, many of which won't change their API or do a complete core
redesign of their library just to accomodate closures. For example, I'm not
so sure that the swing library is going to be updated with an all-new event
handling system so that you can e.g. implement mouseOver with a closure.
--Reinier Zwitserloot
On Fri, Feb 19, 2010 at 5:58 AM, Joshua Bloch <jjb at google.com> wrote:
> As I'm sure you're aware, I'm very much in favor of the goal of the Lambda
> conversion: the new syntax (or something like it) should be usable in
> combination with existing constructs that require a "function object" such
> as a Comparator or (perhaps) a TimerTask. But I'm increasingly skeptical
> that the Lambda conversion (as described in the proposal) is the best way
> to
> achieve this.
>
> I'm skeptical for two reasons. The first concerns the semantics. Simply
> put,
> function types just get in the way when what you want is a SAM type. They
> raise all sorts of thorny issues, many of which we've been discussing
> recently. Is the function-typed object the same object as the SAM-typed
> object, or are there two objects involved? Is there any way to access the
> members of the SAM type? And so on.
>
> The second reason I'm skeptical concerns performance. The latest spec
> draft
> says this:
>
> Implementing lambda conversion will likely generate new objects to wrap or
> > delegate to the lambda expression. This is acceptable in assignment and
> > method invocation conversion contexts, but not in a casting conversion
> > context. (See
> >
> http://mail.openjdk.java.net/pipermail/lambda-dev/2010-January/000449.html
> > )
>
>
> I fear that this will have disastrous performance consequences. Presented
> with a lovely new syntax, programmers will naturally use it, e.g., to make
> Comparators:
>
> Arrays.sort(a, #(String s1, String s2)(return s1.length - s2.length));
>
> But the comparator's sole method is invoked in the inner loop of the sort!
> The slowdown caused by the delegation will add to the constant factor of
> the
> (n log n) sort. This could be very costly! I believe it violates a
> fundamental tenet of Java's design, which has been called *transparency*:
> magic should be kept to a minimum, and the code should reflect its
> performance (to the extent that that's feasible in this day and age). The
> for-each loop, by contrast, does not create an Iterator when traversing an
> array, so it runs as fast as the traditional for loop that it replaces.
> This
> was very important to me when we were designing the for-each construct, and
> I'm glad we did it the way we did.
>
> Therefore, I think we should *very *seriously consider an alternative
> design
> that uses a slightly different syntax when furnishing instances of SAM
> types
> that it does when furnishing instances of function types. Call them
> SAM-lambdas and function-lambads (for the time being). Perhaps the SAM
> lambdas could take the type as a mandatory argument, to simplify the
> compiler's job:
>
> Arrays.sort(a, #Comparator(String s1, String s2)(return s1.length -
> s2.length));
>
> I have no idea whether this is the best syntax, or even an acceptable
> syntax. The important point is that we need something that:
>
> (1) Interoperates with existing methods that require "function objects"
> (2) Provides performance equal to current idioms, and
> (3) Provide conciseness close to that of lambdas (as specified in the
> current proposal)
>
> As a clarification, I am not arguing for the elimination of function types;
> rather I'm arguing that they get in the way of "interoperable function
> objects." so we need two separate syntaxes, one for function types and one
> for SAM types.
>
> Josh
>
>
More information about the lambda-dev
mailing list