Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Good gosh J7 lambdas/closures are looking worse by the day

51 views
Skip to first unread message

Michael Neale

unread,
May 31, 2010, 1:58:01 AM5/31/10
to The Java Posse
http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-of-closures/comment-page-1/#comment-2023

I guess most of the attention has been on the semantics (and rightly
so) but wow... just wow.

(sorry to interupt the appleposse with java news).

Mark Derricutt

unread,
May 31, 2010, 2:07:31 AM5/31/10
to java...@googlegroups.com
I realllllly don't like the look of them.  If they'd reused { } around the actual method call I'd be much happier.  But reusing ()?


--
Pull me down under...

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.


Russel Winder

unread,
May 31, 2010, 2:21:11 AM5/31/10
to java...@googlegroups.com

Is there a page with the proposal set out? Have the authors of the
earlier proposals written up anything about this?

--
Russel.
=============================================================================
Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel...@ekiga.net
41 Buckmaster Road m: +44 7770 465 077 xmpp: rus...@russel.org.uk
London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder

signature.asc

Reinier Zwitserloot

unread,
May 31, 2010, 6:08:52 AM5/31/10
to The Java Posse
Here's a very short rundown on the official syntax, with a link to the
last known proposal at the end. The current status quo isn't, as far
as I know, 100% the same as the 'official' proposal, because a new
version of the spec hasn't been released in months. There's also been
an encyclopedia's worth of traffic on concerns and disadvantages on
lambda-dev, but none of those have been discussed by Mark Reinhold,
Alex Buckley, Maurizio Cimadamore, or Brian Goetz, who all seem to be
involved in writing specs and implementations.

closures themselves come in two flavours. Either form is an
expression, whose type is a closure type:

inline expression form:

#(parameter list) ( expression )

block form:

#(parameter list) { any number of statements; }


The first form is syntax sugar for:

#(parameter list) { return expression; }


So, you can write:

Object plusClosure = #(int a, int b) (a+b);

which is the same thing as writing:

Object plusClosureLongForm = #(int a, int b) {return a + b;};

[Justification: In practice blocks have to be written in standard
style, so, line breaks after opening brace and before closing brace,
lest it look like a semi-colon party, but that means all closures are
multi-line, even very simple ones, such as plus, so, there's a short-
hand form if you can express the body of a closure as a single
expression. Also, inferring parameters is essentially impossible but
inferring return type and checked exceptions isn't, and closures
should be simple (and syntactically very brief), hence the inference.]

Note that 'long returns' doesn't work, you can't break or continue a
loop that your closure definition is in, nor can you return from the
method that your closure definition is in.

Also, the closure captures all variables from outer scope but you
can't actually interact with them unless they are final or effectively
final (effectively final = not marked final, but wouldn't cause an
error if they were marked as such).

The full type signature of a closure consists of 3 properties:

A) Parameter List. Read from the actual parameter list in the closure
definition.
B) Return Type. Inferred from the return statement (block form) or the
type of the expression (inline expression form)
C) (checked) throwables thrown. Inferred.

Obviously assigning a closure to an "Object" variable isn't very
useful. There are two useful type concepts you can assign them to,
function types and SAMs.

Function Types. These look like this:

#int(int, int)(throws IOException | SQLException) plusClosure = #(int
a, int b) (a+b);

[yes, good lord, that's some horrible syntax, I know - also the
official 1.5 spec on function syntax is riddled with errors particular
in regards to the throws syntax; alternatives that also might be valid
depending on where you look in the spec is "(throws IOException,
SQLException)" and just "(IOException, SQLException)".

justification: Without the extra parens around the throws clause the
parsing rule wouldn't terminate which isn't legal in LL(k) grammars
such as the ones used by most java parsers including javac. Or
something. I was a bit fuzzy on this, you may want to check lambda-
dev.]

function types can be 'executed' by using the dot. For example:

assert 15 == plusClosure.(5, 10);

[justification: In java, method names and variable names are separate
namespaces, so just closureVarName() would be looking in the wrong
namespace!]

Closures can also be assigned to SAM types. A SAM type is any type
that is (1) abstract and (2) has only one undefined method in it. In
other words, any interface that mentions only 1 method, and any
abstract class where all but 1 method has an implementation. Like
FileFilter and Runnable. Thus, this would work just fine:

Runnable r = #() {System.out.println("Hello, World!");};
r.run(); //Will say hi to world.
r.(); //This wouldn't be legal; r is a Runnable, not a #()().

The mechanics for realizing that the above closure declaration, which
is of type #()(), can be 'fitted' safely into a java.lang.Runnable
SAM, requires lots of complex inference rules. This inference includes
the reasoning that returning something is compatible with returning
nothing, an inference that doesn't occur anywhere else in java. E.g:

#void(Integer a) = #(Number a) (a);

is legal. If you throw enough generics in the mix, the errors are
going to balloon into gobbledygook. Nevertheless, SAMs are what
today's java libraries run on, so any closure proposal that cannot
'autobox' themselves into a SAM type would be even worse.


"this" in a closure refers to the closure object. This seems nuts but
has been added for the benefit of allowing closures to recurse into
themselves. However, you'd get an endless loop when trying to infer
return type if you actually returned 'this', so the following is
explicitly defined as a compiler error:

Object closure = #() (this); //Infer the return type on this miracle!



The actual way closure types are created most likely will involve
generics of some sort, so arrays of closure types, like so:

#()[] = new #()[10];

aren't legal for the same reason you can't write new T[10];


Link: http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt


On May 31, 8:07 am, Mark Derricutt <m...@talios.com> wrote:
> I realllllly don't like the look of them.  If they'd reused { } around the
> actual method call I'd be much happier.  But reusing ()?
>
> --
> Pull me down under...
>
> On Mon, May 31, 2010 at 5:58 PM, Michael Neale <michael.ne...@gmail.com>wrote:
>
>
>
>
>
> >http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-o...
>
> > I guess most of the attention has been on the semantics (and rightly
> > so) but wow... just wow.
>
> > (sorry to interupt the appleposse with java news).
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "The Java Posse" group.
> > To post to this group, send email to java...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > .

Casper Bang

unread,
May 31, 2010, 6:49:12 AM5/31/10
to The Java Posse
Wow that's ugly. Source code obfuscaters are going to have a blast.

Roel Spilker

unread,
May 31, 2010, 8:46:29 AM5/31/10
to java...@googlegroups.com
> Closures can also be assigned to SAM types. A SAM type is any type that is (1) abstract and
> (2) has only one undefined method in it.
> In other words, any interface that mentions only 1 method, and any abstract class where all
> but 1 method has an implementation. Like FileFilter and Runnable.

If an interface declares methods already defined in Object, they don't count either...

For instance, the interface java.util.Comparator has two methods:

int compare(T o1, T o2);
boolean equals(Object obj);

The second method is in there because it has some javadoc on it. Since Object has a method with the same signature, Comparator still qualifies as a SAM.

Roel

Josh McDonald

unread,
May 31, 2010, 10:46:28 PM5/31/10
to java...@googlegroups.com
Ew, this reeks of "making the compiler-writer's job easy". There must be a nicer solution, even within the narrow guidelines of the problem. Even Obj-C's blocks are nicer than this (in Syntax at least).

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.




--
"Therefore, send not to know For whom the bell tolls. It tolls for thee."

Josh 'G-Funk' McDonald
  -  jo...@joshmcdonald.info
  -  http://twitter.com/sophistifunk
  -  http://flex.joshmcdonald.info/

Michael Neale

unread,
Jun 1, 2010, 1:12:23 AM6/1/10
to The Java Posse
I think it shows it in its worst light, when others show examples it
is OK I guess...

I guess I am more interested in the semantics given that other
languages are far more useful to me (and interesting as well) thus
interop matters if this will be used in JDK apis. Otherwise it is
really hard to care.

On Jun 1, 12:46 pm, Josh McDonald <j...@joshmcdonald.info> wrote:
> Ew, this reeks of "making the compiler-writer's job easy". There must be a
> nicer solution, even within the narrow guidelines of the problem. Even
> Obj-C's blocks are nicer than this (in Syntax at least).
>
> On 31 May 2010 15:58, Michael Neale <michael.ne...@gmail.com> wrote:
>
>
>
>
>
>
>
> >http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-o...
>
> > I guess most of the attention has been on the semantics (and rightly
> > so) but wow... just wow.
>
> > (sorry to interupt the appleposse with java news).
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "The Java Posse" group.
> > To post to this group, send email to java...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.
>
> --
> "Therefore, send not to know For whom the bell tolls. It tolls for thee."
>
> Josh 'G-Funk' McDonald
>   -  j...@joshmcdonald.info

Josh McDonald

unread,
Jun 1, 2010, 1:25:11 AM6/1/10
to java...@googlegroups.com
Agreed, I'm far more interested in the JVM having a standard "function" type and invocation semantics than the syntax within Java source.

To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.




--
"Therefore, send not to know For whom the bell tolls. It tolls for thee."

Josh 'G-Funk' McDonald
  -  jo...@joshmcdonald.info

Moandji Ezana

unread,
Jun 1, 2010, 4:35:26 AM6/1/10
to java...@googlegroups.com
On Tue, Jun 1, 2010 at 7:12 AM, Michael Neale <michae...@gmail.com> wrote:
I think it shows it in its worst light, when others show examples it
is OK I guess...

I agree, I don't think they're particularly ugly. Taking a simple, but real, example:

List<String> userNames = userList.map(#(User u) {
  u.getName();
});

I can't see anything so terrible or unreadable about that.

Moandji

Kevin Wright

unread,
Jun 1, 2010, 4:56:01 AM6/1/10
to java...@googlegroups.com
Syntax wise, we can be a lot smarter by moving to another JVM language:

  val userNames = userList.map(_.name)
or
  val userNames = userList map _.name 

(both valid Scala)

So I'm definitely in the group here that's behind making this standardised at the bytecode level.  The overriding need for backward compatibility just makes it impossible to do anything truly elegant in Java, but this can just be considered a mere triviality nowadays.


--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.



--
Kevin Wright

mail/google talk: kev.lee...@gmail.com
wave: kev.lee...@googlewave.com
skype: kev.lee.wright
twitter: @thecoda

B Smith-Mannschott

unread,
Jun 1, 2010, 6:54:36 AM6/1/10
to java...@googlegroups.com

hhmmm...

wouldn't that be

List<String> userNames = userList.map(#(User u)(
u.getName() // note: round parens, no ";", implicit "return"
));

or

List<String> userNames = userList.map(#(User u){

return u.getName(); // note: "return"
});

But yea, it's not so bad, considering that it's Java.

// Ben

Reinier Zwitserloot

unread,
Jun 1, 2010, 7:28:12 AM6/1/10
to The Java Posse
A clarifying comment by Maurizio on lambda-dev claims that they are
currently implementing something that's similar to the straw man
presented by Mark Reinhold at Devoxx '09, with some of the tough
questions in it removed (such as using .() instead of plain parens to
'execute' a closure), so the widespread discussion on lambda-dev can
at least experiment better.

In otherwords, 'making the compiler-writer's job easy' is apparently
part of the plan, at least for now.

A standard function type in the JVM *already exists* in the jdk7
specs; it's called MethodHandle. There are already calls going out
amongst the alternative languages on the JVM crowd to start switching
to it. Also, partly motivated by the closures stuff, MethodHandle
objects will most likely gain a JVM-based 'asSam()' method which means
at least some of the structural typing that other languages offer can
be done 'natively' instead of working by using a lot of reflection
magic. So, Josh, Michael, time to lobby your friendly local
alternative language developer to get on the bandwagon :)

On Jun 1, 4:46 am, Josh McDonald <j...@joshmcdonald.info> wrote:
> Ew, this reeks of "making the compiler-writer's job easy". There must be a
> nicer solution, even within the narrow guidelines of the problem. Even
> Obj-C's blocks are nicer than this (in Syntax at least).
>
> On 31 May 2010 15:58, Michael Neale <michael.ne...@gmail.com> wrote:
>
>
>
>
>
>
>
> >http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-o...
>
> > I guess most of the attention has been on the semantics (and rightly
> > so) but wow... just wow.
>
> > (sorry to interupt the appleposse with java news).
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "The Java Posse" group.
> > To post to this group, send email to java...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.
>
> --
> "Therefore, send not to know For whom the bell tolls. It tolls for thee."
>
> Josh 'G-Funk' McDonald
>   -  j...@joshmcdonald.info

Reinier Zwitserloot

unread,
Jun 1, 2010, 7:30:26 AM6/1/10
to The Java Posse
Almost, Moandji. This would be the syntax you're looking for in this
particular example:

List<String> userNames = userList.map(#(User u) (u.getName()));

Or, alternatively (both are legit):

List<String> userNames = userList.map(#(User u) {
return u.getName();
});

If I put them in a bad light, I apologize - that wasn't my intent. My
intent was to simply state the proposal, and inject a little despair
into the crazy syntax for function -types-. The syntax for the
closures themselves is fine, and, in fact, one of the few that really
works well with existing java style guides (braces imply newlines,
etc).

On Jun 1, 10:35 am, Moandji Ezana <mwa...@gmail.com> wrote:

Reinier Zwitserloot

unread,
Jun 1, 2010, 7:32:38 AM6/1/10
to The Java Posse
Oh, yeah, we'll just move every single existing java programmer over.
Easy peasy.

I get really annoyed at people who have this 'oh, give up java
already' vibe. If you don't care, that's fine. Why don't you go and be
positive on the scala mailing list, instead of being negative here?
Some of us are trying to make java a better language. If you'd rather
torch java's future to increase scala adoption, I don't want to talk
to you. The more languages the merrier, let them win on their merits,
not by the demerits of other languages. Also, it's all on the JVM.
When one JVM language gains strength, that solidifies the JVM as a
platform, which is good for all JVM languages. I want a strong Scala
*AND* a strong Java.
> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.
>
> --
> Kevin Wright
>
> mail/google talk: kev.lee.wri...@gmail.com
> wave: kev.lee.wri...@googlewave.com
> skype: kev.lee.wright
> twitter: @thecoda

Kevin Wright

unread,
Jun 1, 2010, 8:41:05 AM6/1/10
to java...@googlegroups.com

Quite the opposite, I want to promote java-the-platform vs .net, ruby, etc.

Java is a great language if you want compatibility all the way back to 1.0 code, but in terms of having contemporary features and being fun to use it's already lost a great deal of mindshare.

Scala is, frankly, the lowest impact change for java developers willing to move to a better integrated functional syntax (at the cost of legacy functionality)

I *could* promote Java by defending an outdated legacy syntax that must be kept for reasons of backward-compatibility.  I could also promote Star Trek by shouting down anyone who says that Kirk's character is over-acted.  But to me, the true essence of Star Trek is perhaps better captured with Patrick Stewart at the helm...

And so it is with Java vs Scala, we may mourn the loss of mini-skirts from time to time (who doesn't?).  Nevertheless, the end product is arguably better, and you have to admit that holo-decks are pretty cool - there are many stories that just wouldn't have been written without them (a bit like built-in FP then).

So did Star Trek NG denigrate the original series?  I'd like to think not - it's full of nostalgia for me.  I'd also like to think that Scala isn't denigrating Java, it's just the future of the same universe.


As for Scala mailing lists?  Yes, I'm a frequent contributor there, where they boldly go to some amazing new places at times.  The best part is that we manage to do so without the dilithium crystals failing every third episode, and I'm finding that I really don't miss it as a plot element all that much.


On 1 Jun 2010 12:32, "Reinier Zwitserloot" <rein...@gmail.com> wrote:

Oh, yeah, we'll just move every single existing java programmer over.
Easy peasy.

I get really annoyed at people who have this 'oh, give up java
already' vibe. If you don't care, that's fine. Why don't you go and be
positive on the scala mailing list, instead of being negative here?
Some of us are trying to make java a better language. If you'd rather
torch java's future to increase scala adoption, I don't want to talk
to you. The more languages the merrier, let them win on their merits,
not by the demerits of other languages. Also, it's all on the JVM.
When one JVM language gains strength, that solidifies the JVM as a
platform, which is good for all JVM languages. I want a strong Scala
*AND* a strong Java.


On Jun 1, 10:56 am, Kevin Wright <kev.lee.wri...@gmail.com> wrote:

> Syntax wise, we can be a lot s...

> On 1 June 2010 09:35, Moandji Ezana <mwa...@gmail.com> wrote:
>
>
>
>
>
> > On Tue, Jun 1, 2010 at 7:12 AM, Michael Neale <michael.ne...@gmail.com>wrote:

>
> >> I think it shows it in its worst light, when others show examples it
> >> is OK I guess...
>

...

> > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>

> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.

>...

> mail/google talk: kev.lee.wri...@gmail.com
> wave: kev.lee.wri...@googlewave.com

> skype: kev.lee.wright
> twitter: @thecoda

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group...

Peter Becker

unread,
Jun 1, 2010, 4:46:31 AM6/1/10
to java...@googlegroups.com
Serious question (still trying to get my head around the syntax, but too busy (i.e. lazy) to look it up):

Shouldn't this be either


  List<String> userNames = userList.map(#(User u) {
    return u.getName();
  });

or

  List<String> userNames = userList.map(#(User u)(u.getName());

? I thought the curly brace variants requires a proper Java method body. Or did I get that wrong?

I don't mind that first variant, the variant with the single expression is a bit high on parentheses overload for my taste.

   Peter

Alexey Zinger

unread,
Jun 1, 2010, 2:04:33 PM6/1/10
to java...@googlegroups.com
So basically, this is just syntax sugar around single-method anonymous inner classes.  I'm not saying it's the end of the world, but they aren't closures strictly speaking.  Everything I ever read about what differentiates closures from anonymous inner classes (control flow, lexical scoping) is untouched as compared to what we do already with more verbose syntax.
 
Alexey
2001 Honda CBR600F4i (CCS)
2002 Suzuki Bandit 1200S
1992 Kawasaki EX500
http://azinger.blogspot.com
http://bsheet.sourceforge.net
http://wcollage.sourceforge.net



From: Reinier Zwitserloot <rein...@gmail.com>
To: The Java Posse <java...@googlegroups.com>
Sent: Mon, May 31, 2010 6:08:52 AM
Subject: [The Java Posse] Re: Good gosh J7 lambdas/closures are looking worse by the day
> > javaposse+unsub...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>

> > .
> > For more options, visit this group at
> >http://groups.google.com/group/javaposse?hl=en.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+unsub...@googlegroups.com.

Casper Bang

unread,
Jun 1, 2010, 2:41:15 PM6/1/10
to The Java Posse
On Jun 1, 8:04 pm, Alexey Zinger <inline_f...@yahoo.com> wrote:
> So basically, this is just syntax sugar around single-method anonymous inner classes.  I'm not saying it's the end of the world, but they aren't closures strictly speaking.  Everything I ever read about what differentiates closures from anonymous inner classes (control flow, lexical scoping) is untouched as compared to what we do already with more verbose syntax.

Yeah that was my conclusion as well; that we will have to continue to
put variables into a one-dim array in order to hoist it from stack to
heap and avoid the annoying "final limitation". This does not match
Neal Gafter's definition of a closure. Or did I misunderstand?

Kevin Wright

unread,
Jun 1, 2010, 3:07:58 PM6/1/10
to java...@googlegroups.com
Sadly not, from my understanding of the proposal :(

What really counts though is that we get 1st-class method handles.  That then allows interop between the various JVM languages, as well as any "hoisting" technique in the book (including compiler-generated approaches used by Scala, Clojure, et. al.)

When we consider that Java was able to add both inner classes and generics without changing the bytecode, you get a better feel of what innovation might be possible on to of this minor addition...

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.




--

Moandji Ezana

unread,
Jun 1, 2010, 3:50:58 PM6/1/10
to java...@googlegroups.com
I apologise to all for forgetting the return keyword. It was a quickly-written email using a language feature I'd spent a total of 5 minutes looking at. My point was just that it's not too ugly if you space it out a little. That said, I'm one of those people who don't get what the big deal is about removing semi-colons.

So basically, this is just syntax sugar around single-method anonymous inner classes.

Is that such a bad thing? What would, for example, control flow make possible that couldn't be done otherwise?

What really counts though is that we get 1st-class method handles.

Agreed. That's pretty awesome. Also, the prospect that the VM might be able to make dynamic languages as fast or nearly as fast as static ones.

the annoying "final limitation"

What's the actual reason for this? It's so easy to get around that it doesn't seem like it should exist at all. 

Moandji

Kevin Wright

unread,
Jun 1, 2010, 4:07:33 PM6/1/10
to java...@googlegroups.com
On 1 June 2010 20:50, Moandji Ezana <mwa...@gmail.com> wrote:

What really counts though is that we get 1st-class method handles.

Agreed. That's pretty awesome. Also, the prospect that the VM might be able to make dynamic languages as fast or nearly as fast as static ones.


Hopefully, though the big win for dynamic languages here is invokedynamic, not method handles.

It's also worth noting that all of the general purpose JVM languages (except Java) already have some form of closure, whether dynamically (JRuby, Groovy) or statically typed (Scala), and performance in the space is pretty damn good.  The significant gain then is not in performance, but in interop between them all.


 

Casper Bang

unread,
Jun 1, 2010, 4:27:58 PM6/1/10
to The Java Posse
> What's the actual reason for this? It's so easy to get around that it
> doesn't seem like it should exist at all.

Inner classes never really access the local variable, but rather a
snapshot of it taken at the time the class was instantiated and passed
along to a new stack frame. That was how it originally got
implemented, probably for performance reasons since they were meant
for specifying callbacks to UI libraries (Instead of native events/
delegates/methods-pointers) and the heap is a lot more expensive to
access than the stack?!

Alexey

unread,
Jun 1, 2010, 4:33:18 PM6/1/10
to The Java Posse
On Jun 1, 3:50 pm, Moandji Ezana <mwa...@gmail.com> wrote:
> > So basically, this is just syntax sugar around single-method anonymous inner
> > classes.
>
> Is that such a bad thing? What would, for example, control flow make
> possible that couldn't be done otherwise?

To me, it's not so much a question of good or bad at this point, but
what we're actually getting. When CICE and BGGA discussions were
happening, things like non-local control flow were explicitly
discussed:
* http://www.javac.info/closures-v05.html
* http://www.javac.info/bloch-closures-controversy.ppt

As a quick realistic example, suppose you want to support resource
closing using a Closeable interface. With Java 7 syntax, you might
write something akin to this:

public static void withResource(Closeable resource, #() block)
{
block.();
resource.close();
}

and somewhere else:

// let's imagine that SQLConnection implements Closeable
SQLConnection conn = ...;
withResource(conn, #() {
// do stuff
});

Swell, except, it turns out SQLConnection.close() might throw
SQLException. How do we express that and how does it fit in the flow
of control? If it was a true closure, the definition of withResource
would not change, because the enclosing block (the code that calls it)
would be able to handle exceptions that come out of the closure. But
in our current situation, we have to express this notion that
SQLException's implementation of close has to throw some kind of
exception as part of the type of the "closure" (bring on the throws
type variance hell) and subsequently in withResource implementation.
This significantly muddies the waters.

Now, don't get me wrong, I think this will be useful and we'll get
plenty done with it. But what I'm saying here is that this gives us
very little that we don't already have. This is just syntax on top of
already existing patterns. Yes, it'll make code prettier and probably
more readable in most cases, but the boat on the big gains either has
long sailed or was never in the harbor to begin with.

Colin Decker

unread,
Jun 1, 2010, 4:30:21 PM6/1/10
to java...@googlegroups.com
From my understanding it's planned to allow the use of non-final local variables in lambdas, though they may have to be marked with a keyword like "shared" or an annotation @Shared to indicate the intent. See "Type 3 lambdas - functions capturing mutable state" in the initial translation document draft: http://cr.openjdk.java.net/~mcimadamore/lambda_trans.pdf.

Colin

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

Reinier Zwitserloot

unread,
Jun 1, 2010, 9:40:38 PM6/1/10
to The Java Posse
Learning java closure syntax is more complicated than learning scala?
You've got to be kidding me.

Reinier Zwitserloot

unread,
Jun 1, 2010, 9:46:13 PM6/1/10
to The Java Posse
They DO capture all variables from lexical scope. They then add the
compiler limitation where the compiler will understand what you mean
but refuse to compile it if you access a mutable local variable. For
good reasons.

control flow, if I can presume you mean "long" returns / breaks /
continues, have been left out for now because they can most easily be
added later, and are a gigantic source of complexity.

(think about it - what happens when you 'long return' out of a method
that's already long exited, because the closure has been stored in a
field someplace and executed later? Or, what should happen if a
closure that is run in another thread tries to 'break' out of a still
running for loop? That for loop is now running in another thread
compared to the closure, so - should two threads dovetail their way
through a for loop? That's going to be hard to make work! In practice
you need to add the notion of 'unescaping' closures to either the type
system or the compiler's analysis. You see how the complexity starts
adding up quickly).

You're technically right in that the term 'closure' is being slightly
overextended here. However, just like "HTML5" doesn't actually mean
you use features from the HTML5 spec, "AJAX" does not mean you use XML
(or even an XmlHttpRequest object), and "javascript" has nothing to do
with "java", terms in the programming world change meaning all the
time. In java land, "closures" currently means "code blocks". I'll
join you in lamenting the loss of clarity caused by this confusion,
but, it happened. No way to put this genie back in its box.

On Jun 1, 8:04 pm, Alexey Zinger <inline_f...@yahoo.com> wrote:
> So basically, this is just syntax sugar around single-method anonymous inner classes.  I'm not saying it's the end of the world, but they aren't closures strictly speaking.  Everything I ever read about what differentiates closures from anonymous inner classes (control flow, lexical scoping) is untouched as compared to what we do already with more verbose syntax.
>
>  Alexey
> 2001 Honda CBR600F4i (CCS)
> 2002 Suzuki Bandit 1200S
> 1992 Kawasaki EX500http://azinger.blogspot.comhttp://bsheet.sourceforge.nethttp://wcollage.sourceforge.net
>
> ________________________________
> From: Reinier Zwitserloot <reini...@gmail.com>
> Link:http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/2010021...
>
> On May 31, 8:07 am, Mark Derricutt <m...@talios.com> wrote:
>
>
>
>
>
> > I realllllly don't like the look of them.  If they'd reused { } around the
> > actual method call I'd be much happier.  But reusing ()?
>
> > --
> > Pull me down under...
>
> > On Mon, May 31, 2010 at 5:58 PM, Michael Neale <michael.ne...@gmail.com>wrote:
>
> > >http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-o...
>
> > > I guess most of the attention has been on the semantics (and rightly
> > > so) but wow... just wow.
>
> > > (sorry to interupt the appleposse with java news).
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > > "The Java Posse" group.
> > > To post to this group, send email to java...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > javaposse+...@googlegroups.com<javaposse%2Bunsubscribe@googlegroups .com>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/javaposse?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "The Java Posse" group.
> To post to this group, send email to java...@googlegroups.com.
> To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

Reinier Zwitserloot

unread,
Jun 1, 2010, 9:51:29 PM6/1/10
to The Java Posse
There's ongoing discussion about a keyword to mark a variable as heap-
hosted. Also, if you're using 1-dim arrays you're doing it wrong. Use
AtomicReference/AtomicInteger/AtomicDouble/etcetera instead.

Neal Gafter's definition of a closure is miles away from what we're
getting. Fortunately.

NB: The 'final limitation' exists because of confusion. For example,
what does this print:

Runnable[] r = new Runnable[3];
for (int i = 0; i < 3; i++) r[i] = #() {System.out.print(i);};
for (int i = 0; i < 3; i++) r[i].run();


Looks like it ought to print "123", right? Nope. It would print "333".
Which is confusing. Also, as closures can run anywhere it means local
variables may need synchronizing. So, should we now also allow
"volatile" on local variable declarations and abandon one of the few
last bastions of hope when trying to reason about rocket science
(read: multi-threading stuff), namely that local variables cannot be
shared with other threads, ever, and thus never need thinking about in
regards to locking?

Hence, I fully support at the very least the need to mark such shared
variables with some marker or other. One suggestion is to actually let
the compiler do its thing but emit a warning when it does, which can
be suppressed by adding an @Shared annotation to the local var.
Another one is that it's not legal java code unless you add either
"shared" (new context sensitive keyword) or "public" to the local var
declaration (existing keyword). A final one is that AtomicReference/
Integer/etc are good enough for any man. I like most of those.

Josh McDonald

unread,
Jun 2, 2010, 1:32:41 AM6/2/10
to java...@googlegroups.com
Sweet, thanks for that info :) I didn't know about MethodHandle, I'm assuming it's something like j.l.r.Method, but pre-bound to a specific "this"?

-Josh


On 1 June 2010 21:28, Reinier Zwitserloot <rein...@gmail.com> wrote:
A clarifying comment by Maurizio on lambda-dev claims that they are
currently implementing something that's similar to the straw man
presented by Mark Reinhold at Devoxx '09, with some of the tough
questions in it removed (such as using .() instead of plain parens to
'execute' a closure), so the widespread discussion on lambda-dev can
at least experiment better.

In otherwords, 'making the compiler-writer's job easy' is apparently
part of the plan, at least for now.

A standard function type in the JVM *already exists* in the jdk7
specs; it's called MethodHandle. There are already calls going out
amongst the alternative languages on the JVM crowd to start switching
to it. Also, partly motivated by the closures stuff, MethodHandle
objects will most likely gain a JVM-based 'asSam()' method which means
at least some of the structural typing that other languages offer can
be done 'natively' instead of working by using a lot of reflection
magic. So, Josh, Michael, time to lobby your friendly local
alternative language developer to get on the bandwagon :)





--
"Therefore, send not to know For whom the bell tolls. It tolls for thee."

Josh 'G-Funk' McDonald
  -  jo...@joshmcdonald.info

Kevin Wright

unread,
Jun 2, 2010, 2:16:31 AM6/2/10
to java...@googlegroups.com
On 2 June 2010 02:40, Reinier Zwitserloot <rein...@gmail.com> wrote:
Learning java closure syntax is more complicated than learning scala?
You've got to be kidding me.

I'm assuming that this is the sentence that prompted your outrage:

"Scala is, frankly, the lowest impact change for java developers willing to move to a better integrated functional syntax (at the cost of legacy functionality)"

The key phrase was "better integrated", it was a comparative, but to what?  To Java's proposed syntax of course!  So I was talking about the lowest impact of the alternatives to Java.  Presumably you don't consider Java to be an alternative to itself?

To avoid any further confusion, I'll rephrase it:

Having a functional syntax that is closely integrated into a language (ideally from the point of conception) is a desirable thing.  Unfortunately, this deep integration is not possible with Java due to backward-compatibility constraints.

For Java developers wanting a syntax that is more natural and effortless than this proposal, it would therefore seem wise to look beyond Java-the-Language.  In this broader space of alternate JVM languages the barrier to entry seems lowest for Scala, thanks to static typing and conscious efforts at making Java-Scala interop effortless.  Scala can be initially used as though it were no more than a tidied-up variant of Java, allowing developers to become productive again in a very short space of time.

 


You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.




--
Kevin Wright

Reinier Zwitserloot

unread,
Jun 2, 2010, 10:10:57 PM6/2/10
to The Java Posse
Not quite. MethodHandles aren't referring to a java library feature;
they are referring to a JVM feature. You can have an object-like
construct on the stack or on the heap, just like any other object or
primitive value, which represents a method invocation-to-be. This may
feel a little bit like a java.lang.reflect.Method object, but it's
different in a few ways:

1) It's a JVM-native concept. j.l.r.Method isn't; j.l.r.Method is a
fairly ordinary class where a bunch of its methods, including for
example 'invoke' are marked as 'native'. There's a difference; there
is no class file for MethodHandle at all, and its spec is much more
closely related to the core JVM C code itself, it's not just a sort of
add-on C file like j.l.r.Method's invoke.

2) The security checks on accessibility are done at the time the
method handle object is created. In other words, if code in A.class
creates a method handle to a private method 'foo' in A.class, and then
gives this method handle to B.class which then executes the method
handle, that works. If you were using j.l.r.Method, that wouldn't,
because j.l.r.Method does its security check on execute. You can of
course make j.l.r.Method work via .setAccessible(true) magic, but that
causes a call to the security manager. Note that the security model
isn't affected; if I have access to a method already I can of course
leak it to whomever I want, simply by wrapping a call to it into e.g.
a Runnable and passing that runnable around.

3) MethodHandles come in a few flavours and have certain flexibilities
(including the notion that MH's have a 'this' referent or not). For
example, there's a JVM-native-ish operation to curry them. (currying =
supplying some but not all parameters, effectively turning them into a
new method that takes less parameters. For example, turning add(int,
int) into add5(int) which always uses '5' as first argument. add5 is
like a new handle with a different signature). Currying without JVM
support is kinda annoying and somewhat pricey, as it would involve
creating a new class, running up permgen, causing a class parse hit,
etcetera.

4) MH's are designed primarily as a language-agnostic method handle
vehicle; they do NOT reflect any particular need for the java language
and are completely unrelated to the closures-for-java (a.k.a. project
lambda) effort, though most likely project lambda will gladly use the
MH feature. MH is being driven primarily by the alternative language
crowd.

5) In general, MHs are designed with speed, speed, speed, speed, and
low memory requirements in mind. Since java 1.4 j.l.r.Method isn't
exactly a sloth either, but MHs should be faster still, and take
considerably less permgen, which is a good thing.

On Jun 2, 7:32 am, Josh McDonald <j...@joshmcdonald.info> wrote:
> Sweet, thanks for that info :) I didn't know about MethodHandle, I'm
> assuming it's something like j.l.r.Method, but pre-bound to a specific
> "this"?
>
> -Josh
>
> On 1 June 2010 21:28, Reinier Zwitserloot <reini...@gmail.com> wrote:
>
>
>
>
>
> > A clarifying comment by Maurizio on lambda-dev claims that they are
> > currently implementing something that's similar to the straw man
> > presented by Mark Reinhold at Devoxx '09, with some of the tough
> > questions in it removed (such as using .() instead of plain parens to
> > 'execute' a closure), so the widespread discussion on lambda-dev can
> > at least experiment better.
>
> > In otherwords, 'making the compiler-writer's job easy' is apparently
> > part of the plan, at least for now.
>
> > A standard function type in the JVM *already exists* in the jdk7
> > specs; it's called MethodHandle. There are already calls going out
> > amongst the alternative languages on the JVM crowd to start switching
> > to it. Also, partly motivated by the closures stuff, MethodHandle
> > objects will most likely gain a JVM-based 'asSam()' method which means
> > at least some of the structural typing that other languages offer can
> > be done 'natively' instead of working by using a lot of reflection
> > magic. So, Josh, Michael, time to lobby your friendly local
> > alternative language developer to get on the bandwagon :)
>
> --
> "Therefore, send not to know For whom the bell tolls. It tolls for thee."
>
> Josh 'G-Funk' McDonald
>   -  j...@joshmcdonald.info

Josh McDonald

unread,
Jun 2, 2010, 10:15:57 PM6/2/10
to java...@googlegroups.com
Sweet, that kicks ass :)

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.


--
"Therefore, send not to know For whom the bell tolls. It tolls for thee."

Josh 'G-Funk' McDonald
  -  jo...@joshmcdonald.info

opinali

unread,
Jun 4, 2010, 11:18:32 PM6/4/10
to The Java Posse
On 1 jun, 22:51, Reinier Zwitserloot <reini...@gmail.com> wrote:
> Neal Gafter's definition of a closure is miles away from what we're
> getting. Fortunately.

If you mean the requirement to capture unrestricted variables (not
just final ones), this is not "Neal's definition", this is everybody's
definition; it's _the_ formal definition of the closures concept
("function with free variables bound in its lexical environment").
Nobody ever discussed that for decades... until Java appeared with its
brain-damaged inner classes, and started teaching a whole generation
that closures are something complex, dangerous, confusing - unless we
protect stupid programmers with some limitations (which also
contradicts decades of experience with previous and current
languages).

A+
Osvaldo

Vince O'Sullivan

unread,
Jun 5, 2010, 2:05:55 AM6/5/10