Java – What are the benefits and disadvantages in the approaches of C#, Java and Scala to Closures/Lambdas/…

cclosuresjavalambdascala

I wonder what the technical implementation differences between C# and Scala are and how both solutions compare to the implementation ideas and concerns voiced in the email Peek Past lambda by Brian Goetz, sent to the mailing list of Project Lambda (JSR 335)?

From the email:

We explored the road of "maybe lambdas should just be inner class
instances, that would be really simple", but eventually came to the
position of "functions are a better direction for the future of the
language".

and further:

The lambdas-are-objects view of the world conflicts with this possible
future. The lambdas-are-functions view of the world does not, and
preserving this flexibility is one of the points in favor of not
burdening lambdas with even the appearance of object-ness.

Conclusion:

Lambdas-are-functions opens doors. Lambdas-are-objects closes them.
We prefer to see those doors left open.

And some comment from a person on the Reddit thread says:

I actually e-mailed Neal Gafter about this and to my limited
understanding of his explaination C# and the current Java design are
quite similar in that Delegates are actually objects and not function
types. It seems like he believes that Java should learn from the
disadvantages of C#'s lambdas and avoid them (much like C# learned
from Java's disadvantages and avoided them in the beginning).

Why does the "Lambdas-are-functions" approach enable more opportunities in the future than "Lambdas-are-objects"? Can someone explain what differences exist and how they would influence how code would be written?

Seeing that things in Scala "just work", I keep thinking that I'm missing something about the approaches taken/proposed in C#/Java (8), probably it is related to concerns about backward-compatibility?

Best Answer

I think the discussion regarding objects vs. functions is a red herring. If the question is, "Is a lambda a function or an object?" the answer should be yes.

That's the point of first-class functions: they aren't treated differently than any other type. Java already manages to mostly ignore the differences between Object and primitive types (and Scala does even better), so whether a lambda is a subclass of Object or is a new primitive type or something else isn't really important for the language. What is important is that you can put your lambdas in collections, pass them around to be called, call them, and do anything else you might want to do with either an object or a method.

Scala accomplishes this by using a wrapper object that has a method called apply which can be invoked with just (), making it look just like a method call. This works splendidly; much of the time you don't need to even care whether you have a method or are calling the apply of a function object.