

State of the Lambda - jondot
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html

======
henrikschroder
> An alternative (or complementary) approach to function types, suggested by
> some early proposals, would have been to introduce a new, structural
> function type. A type like "function from a String and an Object to an int"
> might be expressed as (String,Object)->int. This idea was considered and
> rejected, at least for now, due to several disadvantages:

Too bad they didn't, C# originally had delegates that you had to declare, but
with the addition of generics and lambdas, that system got prettier and
easier. The generic delegate types Func and Action are just that, so I can
have a method that looks like this:

    
    
      private Foo MyMethod(string str, Func<Bar, string, int> func) {
        //...
      }
    

...which means that MyMethod is a method that takes two arguments, the first
is a string, and the second is a method that takes two arguments, a string and
an int, and returns a Bar object. But when I call it, I can use a lambda
expression, like this:

    
    
      var result = MyMethod("hey hey", (s, i) => new Bar(s, i));
    

...which is far from unwieldy. But I can see how checked exceptions would make
it horrible, and I'm glad C# doesn't have those.

~~~
jfager
Using lambdas in Java 8 looks pretty much exactly like your example.

The line you quote from the article is about a proposed way of declaring
lambda types, where instead of

    
    
        private Foo MyMethod(string str, Func<Bar, string, int> func) {
          //...
        }
    

you could write something like

    
    
        private Foo MyMethod(string str, (string,int)->Bar func) {
          //...
        }

------
ScottBurson
> It is our intent to _prohibit_ capture of mutable local variables. The
> reason is that idioms like this:
    
    
      int sum = 0;
      list.forEach(e -> { sum += e.size(); });
    

> are fundamentally serial

An unfortunate decision. Yes, updating such a variable from multiple threads
can cause race conditions. But there are many ways to run into race conditions
when writing multithreaded code, and this doesn't really add a new one.

Furthermore, most code is mostly serial, and the ability to modify captured
variables is a very useful one in serial code. (I've written code like that in
Lisp for decades.) And finally, the restriction is, of course, easily worked
around -- just store the value you want to update in a 1-element array.

So the restriction doesn't really protect anyone from anything -- it just
forces them to use an ugly workaround in order to write their algorithms in a
natural way.

~~~
kevinpet
The motivation is that the question of whether list.forEach (or maybe better,
iterable.forEach) is serial or parallel is to be left up to the implementation
of the collection. Everything related to multi-threaded code since about Java
5 has been about hiding the details of concurrency and allowing programmers to
think about code in a serial fashion, but still get the gains from multi
threaded code.

It's not necessarily about parallelism either -- you could just as easily pass
in a function as some sort of callback that gets called far in the future, for
example,

String error = null; return createClientWithErrorHandler(e -> { error = e; });

What does that even mean? Does the execution context need to be kept hanging
around?

Java already provides good atomic references if you need to have a sum
variable or anything similar.

~~~
ScottBurson
> What does that even mean? Does the execution context need to be kept hanging
> around?

Once the block containing the declaration of 'error' has been exited, the only
way anything could refer to 'error' would be if there were at least one
additional lambda expression in the same block that was closed over the same
binding of 'error'. Two such lambda expressions could thus communicate with
each other through the shared binding.

------
mbell
I'm surprised more people aren't just using Groovy. The performance of Groovy
2.0 on JVM 7 is greatly improved to the point where its a non-issue in 95% of
situations (and you can just drop to java for those portions with no
penalties).

~~~
mgkimsal
I tend to agree with you, but Groovy 2 is still pretty new. In my experience,
most of the hardcode Java shops and devs that rejected Groovy (primarily?)
because of speed are generally slow-adopters, and wouldn't be using Groovy 2
just because it was released a few months ago.

As to speed, I've not benchmarked it on JDK7, so I'm not sure what effect the
InvokeDynamic stuff has yet, but @CompileStatic annotation helps a lot.

My fibonacci stuff at <https://github.com/mgkimsal/newgroovy2> (did a
presentation on groovy2 last week) showed:

fibonacci run of 30:

* pure java (not in the github) - 12ms

* groovy2 compilestatic - 18ms

* groovy2 dynamic with typedefs - 30ms

* groovy2 no typedefs - 500ms

So yes, while @CompileStatic groovy2 is technically approx 40-50% 'slower' in
these tests, the noticeable diff for a lot of projects (especially considering
file and db access will be constants regardless) will be likely negligible.

~~~
vorg
Groovy 2.0 was only released a few months ago, and isn't production ready.
Groovy 2.0 has two jars in it, one with static-compilation and static-
inference grafted on, and the other with optimizations for JDK 7's invoke-
dynamic bytecode. Programmers _can't_ use both static-compilation _and_
invoke-dynamic in the same source file.

Also, both jars seem to have problems. Groovy 2.0.4 was released yesterday
only 2 weeks after version 2.0.2 was released "to fix static compilation and
type inference problems". Grails 2.2-rc-1 (actually the first beta and not a
serious "release candidate" for production use, because the releases called
"beta" are really alphas) has only just been released, the first with Groovy
2.x, with only the static-compilation jar from Groovy 2.0.2 bundled, _not_ the
invoke-dynamic jar.

The facilities of the invoke-dynamic jar might never be merged into the
static-compilation jar. There seems to be some infighting at SpringSource over
who's in control of Groovy. Version 2.0.3 was skipped because the P.M.
"compiled it on the JDK 6 instead of JDK 7 by mistake", which looks like a
political play by Guillaume Laforge, SpringSource's project manager for
Groovy, against Jochen Theodorou, their technical lead who's done most of the
programming work on Groovy since 2004.

A year ago, Laforge hired another developer, Cedric Champeau, to put static
type inference and compilation into Groovy, in order to mitigate a
SpringSource business threat by Alex Tkachman's Groovy++, a static-compilation
addon to Groovy which has since been abandoned. Groovy++ had to switch from
supporting Groovy 1.8 to 1.7 for a while during its development because of
compatibility problems in subsequent beta releases of Groovy, which may have
been deliberate, and at the very least, Groovy++ served as an "inspiration"
for Groovy 2.0's static-compilation jar. It's looking like Theodorou's invoke-
dynamic bytecode optimizations aren't being merged into the static-compilation
jar because of a power play by Laforge and Champeau who control the static-
compilation jar. The project manager is diluting Theodorou's technical
importance to Groovy and thus increasing his own influence.

Concerning your benchmarks of Groovy with Java, you left out Scala and
Clojure, also popular JVM languages, _and_ you chose an algorithm not used
much in business. Both Scala and Clojure have lazy-evaluation in their library
lambdas/functions, as will Java 8. Groovy _only_ enables strict evaluation,
which slows down many computations used in real business programming
scenarios, of which fibonacci isn't one. Lazy-evaluation isn't in the pipeline
for Groovy anytime soon. Its "GDK" utility methods were mostly written early
on by a programmer without the aptitude for developing anything too complex,
such as lambdas with lazy-evaluation. Seems like JDK 8's lambdas, due to ship
in about a year, will be the first time Groovy will enable lazily-evaluated
computations, long after Scala and Clojure. As for the invoke-dynamic bytecode
optimizations being merged into the main jar used by Groovy 2.0 and Grails
2.2, JRuby's long stolen that show. It might never happen with Groovy.

And of course there's no spec for Groovy, unlike Scala's detailed spec or
Clojure's function doc-strings. Without a spec, Groovy is still single-
platform, unlike Clojure and Scala, and many other JVM languages that began
their life somewhere else first.

So I don't think slow adoption by Java shops that were concerned about
Groovy's performance is the reason more businesses don't adopt Groovy. It's
more likely that the static-compilation code isn't production ready, just
laden with problems, political infighting at SpringSource, trailing behind
other languages in lazy-evaluation of lambdas (Clojure, Scala) and invoke-
dynamic optimizations (JRuby), an informal-only spec that changes between
point releases, the names "Groovy" and "G-Strings" evoking drug use and
discrimination against female employees, and a general sense by technical
managers that there's a price to be paid later down the line if they adopt
Groovy.

~~~
blackdrag
As a main Groovy developer, the Jochen Theodorou, that was spoken of above, I
think I have to correct the above quite a bit.

Yes, the distribution contains 2 jars now, one for the groovy parts being
precompiled with the invokedynamic port as well as the invokedynamic
implementation itself and another one. But! The other one is not a static
version. It is the normal dynamic Groovy, that was it before. Of course you
can use the indy jar and use non indy code as well as you can use
@CompileStatic with it. Should there be any problems in mixing indy and static
compilation, please report them, they would be bugs. In both jars indy is
disabled by default and needs to be enabled on the command line or as compiler
option if you want to use it. The problem with having precompiled groovy code
in indy simply is, that it cannot run on a pre jdk7. The alternative would be
to have no indy precompiled stuff in the distribution and we may take this
path later on. So the difference between the jars is, that the second jar has
additionally classes for invokedynamic support and precompiles some stuff
using indy, while the non-indy jar has no indy classes and is compiled like
before. Static compilation has absolutely nothing to do with it. So sorry, but
you say above is large nonsense and please stop spreading non-facts and false
flags. Groovy 2.0.4 was released because of some critical bugs in stub
compiler, that have been a bigger problem to other projects, that want to
release soon a new version. As for Groovy++. If you want to hear the full
story, I will tell it you, but not in public, because I am respecting Alex,
but what I would have to say about this, wouldn't sound like it and is not
explained in a few lines of code. Let us just say that we had some very
negative vibes between us. Him being my boss in the G2One days made things
especially bad.

Then about lazy evaluation... the way I know them is for example generators.
There is an article on the Groovy wiki on how to make generators using
groovy.lang.Closure. I don't think that lambdas in Jdk8 will allow for example
partially uncompiled code or non checked code paths until needed. So the will
effectively not be better than Groovy in terms of laziness.

~~~
vorg
> Should there be any problems in mixing indy and static compilation, please
> report them, they would be bugs

Looks like I misread the announcements about the 2 jars in Groovy 2.0. Perhaps
someone should have corrected me when I first misexplained it in my blog 3
months ago (<http://groovy.codeplex.com/wikipage?title=Blog02#13>).

There are, however, other issues that go back much longer. During 2006-2008 I
wasn't welcomed but instead ignored then ridiculed by many in the Groovy
community. Besides the public stuff, there was much more through back-
channels, which appeared to be instigated by the project managers. Regarding
Groovy++ and static compilation, I started building "GRegexes" atop it so had
a stake in its success. So when in July last year, those project managers
started a parallel project under VMware control to do the same, it looked like
they were again squashing anything not under their own umbrella, despite
advertising API transformation hooks allowing others to independently plug
their own functionality into (Codehaus) Groovy. I started speaking out
publically about their behavior then. Not wanting to give up on Groovy, I
started building a version atop Clojure around December last year. Lo and
behold, within a week after 8 years of neglecting JSR-241, the Groovy project
manager starts writing a tool to generate a "TCK" from the Codehaus Groovy
tests, from which he intends to generate a "spec" automatically. Whatever
tests the current version of the Codehaus implementation of Groovy happens to
pass at the time becomes the latest version of the "spec". Any changes to the
"spec" will effectively be discussions on the Codehaus mailing list and Jira
issues.

After all this it looks like VMware don't really want anything related to
Groovy that's not under their own direct control. Other languages _embrace the
anarchy_ : Perl has CPAN, and v6 has a spec with different implementations.
Ruby has gems and an ISO spec with many implementations, and Rails was built
_outside_ Matz's control afaik by 37signals. Haskell has Hackage and a spec
with many implementations, but the VMware project managers seem to be
discouraging independent development like Groovy++ and GRegexes, and even
stonewalling regarding a spec. I have only respect for your contributions to
Groovy, as well as those of Cedric, Paul, Jeremy, and others I don't know
about, but I have a lot of mistrust with the non-technical overlords at
VMware. Perhaps that was how I misread what they said about the two jars in
Groovy 2.

~~~
blackdrag
Should I have corrected your misread about the announcements? Well I would
have done so if I had read it. I try to concentrate on working and what goes
through the lists. I don't read blogs very often. The normal channel for me is
to ask on the mailing list if there are things unclear. I then try to answer
them as best as I can.

Looking at nabble a bit (I did of course not look at all your messages) I
don't see what you mean with being ignored or not welcomed or ridiculed in
2006-2008. as for the back-channels, that was the situation from 2003 onwards
already. back then a lot happened in IRC for example. The long discussions on
the list have often only been the tip of the iceberg. As for GRegexes... it is
the first time I hear about it. Remember I don't usually read many blogs and
you never mentioned it on the groovy lists. So I am sorry that you have this
problem. I won't say Alex is the only one at fault for this. We offered him a
slow integration path of his "ideas" including a rewrite of the code, because
his code was quite makeshift. He was not interested without getting money. And
getting new founds from VMware is a fight, especially for Groovy. If you think
VMware wants to control anything Groovy, then I think I have to tell you that
this is wrong. Most of VMware doesn't even know Groovy exists. This has pros
(no being bothered too much by marketing) and cons (not getting much in terms
of funds). The part VMware is mostly interested in, is Grails as part of their
products. And they don't care too much about what Grails does exactly either,
as long as it works for them. So I really don't see VMware wanting to have
everything under their control. I mean you complain also about a time long
before main developers have been with VMware. From my perspective the freedom
we have now is more then when there was G2One (there we always had financial
problems). And before G2One is was even difficult to meet. I mean when I
attended the first Paris meeting I was still student and paying everything
myself.

Regarding a spec... We discuss this since... I don't know, since James had the
stupid idea of doing a JSR and then not working on it. Jeremy worked a lot on
it, but in the end he had to stop because of potential copyright issues with
Sun. We asked them if we could take their spec and adapt it for Groovy. That
of course they didn't want. Then we started with a "delta" spec. But actually
this cannot work for two reasons. One is that Groovy has some quite
fundamental changes of the concepts, so a simple "delta" will not do it in
large parts. The other is that they too change the spec over time, making a
"delta" a bit difficult. Well, ok, the later is not such a big deal, if you
have some persons working on this... but we never had anyone but Jeremy. As
for the spec from Guillaume... What you wrote doesn't sound quite right to me.
The idea is to have a document similar to the JLS for Groovy, including code.
This code is to form the TCK, and "directly" executed from that spec. Quite
some tests from our test suite would then go into that spec and the spec will
become part of our build, to ensure we do not accidentally change the spec
with our implementation. If you want to make such a project you are welcome.
But then I suggest not only looking at the very small beginnings at
<https://github.com/glaforge/dokspek> I also suggest we discuss the exact
thing on the list first - and that without letting us be blinded by emotion
please.

------
batgaijin
Hey, it's only been 17 years.

~~~
factorizer
In which Java basically has taken over the world of enterprise programming.
Contrary to fringe languages like Haskell and the like.

~~~
batgaijin
Java forces you to write code in a pretty readable/static manner. Of course
you can write 'bad' Java, but the point is that Java limits expressiveness so
that YOU are replaceable/won't introduce memory issues. That's the whole point
of using Java in the enterprise.

To be clear, I'm not saying anything bad about the JVM.

------
rat87
State of the Lambda December 2011 4th edition

~~~
eranation
Yes, why old news make front page? I guess not everyone is aware of it yet.

------
pacala
> Default methods provide a more object-oriented solution for this problem:
> people.sort(comparing(Person::getLastName));

Yay function pointers.

~~~
rforax
and default methods are traits but it's a secret.

------
spullara
Most of the effort around Lambda in the JVM has now shifted to implementing
the collection libraries. You can follow along here:

[http://mail.openjdk.java.net/pipermail/lambda-libs-spec-
obse...](http://mail.openjdk.java.net/pipermail/lambda-libs-spec-
observers/2012-September/thread.html)

------
ww520
It actually looks pretty good. I can see they spend a lot of effort to make
sure it fits into the existing system, keeping new syntax or new form to the
minimum.

------
jmcdonald-ut
If this helps replace functors I'm all for it.

------
CervezaPorFavor
Fortunately for us, the programming language world isn't as litigious as the
smartphone world.

~~~
simgidacav
I cannot see how to apply the lambda-calculus to smartphones…

~~~
eblackburn
Lamdas are not orignal.

