a convert to lambda-ism

L

Lew

I've been perusing
<http://cr.openjdk.java.net/~mr/lambda/straw-man/>

For the first time in the closures debates, I'm a fan of lambda expressions in
Java now.

Not that I've ever been against them, really, just haven't missed them before.
At this point the state of Java discourse around closures has matured to
where I see clear value in the proposal. It appears that the straw-man
proposal integrates, or at least aims to integrate the best of all the major
proposals.

From the link, 2009/12/10:
"This proposal builds upon the past work of Gilad Bracha, Neal Gafter, James
Gosling, and Peter von der Ahé on BGGA; of Bob Lee, Doug Lea, and Josh Bloch
on CICE; and of Stephen Colebourne and Stefan Shulz on FCM. There is little
here that is new beyond the synthesis of selected elements of those, and
related, proposals."

I note that this positive progress is happening under Oracle's aegis, and is
projected for Java 8. Yes, that's right, they're planning an 8.
 
M

markspace



I've been following, off and on, the development on their mailing list:

<http://mail.openjdk.java.net/pipermail/lambda-dev/>

I believe the latest draft/update is here:

<http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html>

The switch from Java 7 to Java 8 happened a while back. Basically, all
the features planned for Java 7 would have delayed it by at least a
couple of years. So they broke Java 7 into two parts: the easy bits and
the hard bits. Easy bits are going out ASAP in Java 7, the harder stuff
will be delayed and then go out in Java 8.

Weird, but I do think getting something out for Java 7 ASAP was the
right choice.
 
K

Kevin McMurtrie

Lew <[email protected]> said:
I've been perusing
<http://cr.openjdk.java.net/~mr/lambda/straw-man/>

For the first time in the closures debates, I'm a fan of lambda expressions
in
Java now.

Not that I've ever been against them, really, just haven't missed them
before.
At this point the state of Java discourse around closures has matured to
where I see clear value in the proposal. It appears that the straw-man
proposal integrates, or at least aims to integrate the best of all the major
proposals.

From the link, 2009/12/10:
"This proposal builds upon the past work of Gilad Bracha, Neal Gafter, James
Gosling, and Peter von der Ahé on BGGA; of Bob Lee, Doug Lea, and Josh Bloch
on CICE; and of Stephen Colebourne and Stefan Shulz on FCM. There is little
here that is new beyond the synthesis of selected elements of those, and
related, proposals."

I note that this positive progress is happening under Oracle's aegis, and is
projected for Java 8. Yes, that's right, they're planning an 8.

It's awesome that Java will finally support function pointers elegantly.
Creating an interface or enum just to define a wrapper for a function is
cumbersome in many ways.

I'm a little worried about the proposed Lambda syntax having too much
redundancy with regular functions and methods. There should be only one
way to write it, else there's risk of Java getting cluttered up like
C/C++.

(Still hoping for unsigned math and contiguous object array allocation)
 
J

Joshua Cranmer

I've been perusing
<http://cr.openjdk.java.net/~mr/lambda/straw-man/>

For the first time in the closures debates, I'm a fan of lambda
expressions in Java now.

The best thing I can say is that it doesn't have BGGA's fanatical
devotion to non-local control flow idioms. Those made a lot of the stuff
just plain complex and confusing, and that alone was enough to sink the
proposal for me.

Now that it looks like the pro-closure camp isn't adhering strictly to
BGGA, I'll revisit my opinions on closures in Java.

I'm not crazy about the syntax, but then again, function pointers have
never had stellar syntax. int (*fp)(int, int), anyone? :) The ability
to just have single expressions I'm not entirely sure about-- #() {
return x + x; } isn't much longer than #()(x + x), and is certainly
somewhat easier to read.

Another minor syntactic note is that introducing the new keyword
`shared' (or rather, introducing it non-breaking ways (!)) seems
unwarranted. If the idea is to limit to the enclosing scope, you could
probably have the same effect if you reused the keyword `public'.

In terms of major semantic concerns, the big question to me is how to
handle the types. How they are actually implemented does leave major
concerns other some generics interactions due to erasure.

I'm also not sure about the extensions method section. While I have had
instances where I would have liked to use it, it's never been a dealbreaker.

All in all, I'll change my stance from `NO!' to `Maybe?'. Although if
enough howling brings back non-local control flow idioms, I'll change it
back to `NO!'.
 
L

Lew

Kevin said:
(Still hoping for unsigned math and contiguous object array allocation)

IIRC, unsigned ints are on the table for Java 8, due out right about the end
of the Mayan calendar.
 
T

Tom Anderson

The best thing I can say is that it doesn't have BGGA's fanatical devotion to
non-local control flow idioms.

Yes. I literally punched the air when i read:

There is no non-local transfer of control in this proposal, in contrast
to BGGA.

I thought i was the only one who thought the 'return returns from the
enclosing scope' was batshit insane.
Those made a lot of the stuff just plain complex and confusing, and that
alone was enough to sink the proposal for me.

Amen to that, brother. Also, it had maximally horrid syntax. Even
Reinhold's 'strictly provisional' syntax is better!
I'm not crazy about the syntax, but then again, function pointers have
never had stellar syntax. int (*fp)(int, int), anyone? :) The ability
to just have single expressions I'm not entirely sure about-- #() {
return x + x; } isn't much longer than #()(x + x), and is certainly
somewhat easier to read.

The terseness lends itself to the typical higher-order-function uses,
like:

List<String> names;
List<Integer> lengths = names.collect(#(String s) (s.length()));

Adding the return to that makes it noticeably, although of course by no
means fatally, clunkier.
Another minor syntactic note is that introducing the new keyword
`shared' (or rather, introducing it non-breaking ways (!)) seems
unwarranted. If the idea is to limit to the enclosing scope, you could
probably have the same effect if you reused the keyword `public'.

Agreed.

And i'm surprised non-shared closed-over variables aren't required to be
declared final, but must only be 'effectively-final'. That seems
un-javalike.
In terms of major semantic concerns, the big question to me is how to
handle the types. How they are actually implemented does leave major
concerns other some generics interactions due to erasure.

Could you expand on that? I don't know how to even begin thinking about
the interaction with types.

Mind you, having seen what's happened to the type system around
invokedynamic, i am no longer sure that such concerns are actually a
roadblock to implementation, sadly.
I'm also not sure about the extensions method section. While I have had
instances where I would have liked to use it, it's never been a
dealbreaker.

Given that we won't be able to add lambda-aware methods to existing
collection interfaces, because that would break all existing code which
implements them, extension methods are the only way of being able to write
the example i give above, or do anything along those lines (map, filter,
reduce, and friends). Having lambdas but not being able to do those things
would be agonizing.

Also, i really don't like the implicit function conversion. I appreciate
that there are millions of places where we'd like to use first-class
functions where we currently use these 'SAM' (Single Abstract Method - i
had to look it up) types, but i don't think we should be catering to that
in the language. For the most part, the classes which currently demand SAM
types are ones in the standard library (Collections, Arrays, Thread) which
could easily be enlarged to take lambdas too. Where there are interfaces
which we'd like to expand, we can use extension methods:

package java.util.concurrent;

public class ExecutorService {
public static Thread newThread(ThreadFactory self, #void() fn) {
return self.newThread(new Runnable() {
public void run() {
fn();
}
});
}
}

import static ExecutorService.newThread extends ThreadFactory; // my suggestion

ThreadFactory factory;
Thread t = factory.newThread(#() {doStuff();});

There are tons of other things extension methods would be useful for. I
think once you had them, you'd wonder how you ever lived without them. For
instance, you'll immediately be able to say:

import java.util.List;
import static java.util.Collections.sort extends java.util.List;

List things;
things.sort();

Wouldn't that be nice?

tom
 
T

Tom Anderson


Urgh. This is even more SAM-centric. Why is it impossible for anyone to
come up with a lambda proposal without latching on to at least one
terrible idea?

The concrete syntax is worse, too.
The switch from Java 7 to Java 8 happened a while back. Basically, all
the features planned for Java 7 would have delayed it by at least a
couple of years. So they broke Java 7 into two parts: the easy bits and
the hard bits. Easy bits are going out ASAP in Java 7, the harder stuff
will be delayed and then go out in Java 8.

Weird, but I do think getting something out for Java 7 ASAP was the
right choice.

Whatever happened to the proud tradition of x.5 releases, eh? Does nobody
remember System 7.5 and 8.5 on the Mac? Are we seriously going to go from
1.6.0 to 1.7.0?

tom
 
J

Jim Janney

Tom Anderson said:
Yes. I literally punched the air when i read:

There is no non-local transfer of control in this proposal, in contrast
to BGGA.

I thought i was the only one who thought the 'return returns from the
enclosing scope' was batshit insane.


Amen to that, brother. Also, it had maximally horrid syntax. Even
Reinhold's 'strictly provisional' syntax is better!


The terseness lends itself to the typical higher-order-function uses,
like:

List<String> names;
List<Integer> lengths = names.collect(#(String s) (s.length()));

Adding the return to that makes it noticeably, although of course by
no means fatally, clunkier.


Agreed.

And i'm surprised non-shared closed-over variables aren't required to
be declared final, but must only be 'effectively-final'. That seems
un-javalike.


Could you expand on that? I don't know how to even begin thinking
about the interaction with types.

Mind you, having seen what's happened to the type system around
invokedynamic, i am no longer sure that such concerns are actually a
roadblock to implementation, sadly.


Given that we won't be able to add lambda-aware methods to existing
collection interfaces, because that would break all existing code
which implements them, extension methods are the only way of being
able to write the example i give above, or do anything along those
lines (map, filter, reduce, and friends). Having lambdas but not being
able to do those things would be agonizing.

Also, i really don't like the implicit function conversion. I
appreciate that there are millions of places where we'd like to use
first-class functions where we currently use these 'SAM' (Single
Abstract Method - i had to look it up) types, but i don't think we
should be catering to that in the language. For the most part, the
classes which currently demand SAM types are ones in the standard
library (Collections, Arrays, Thread) which could easily be enlarged
to take lambdas too. Where there are interfaces which we'd like to
expand, we can use extension methods:

package java.util.concurrent;

public class ExecutorService {
public static Thread newThread(ThreadFactory self, #void() fn) {
return self.newThread(new Runnable() {
public void run() {
fn();
}
});
}
}

import static ExecutorService.newThread extends ThreadFactory; // my suggestion

ThreadFactory factory;
Thread t = factory.newThread(#() {doStuff();});

There are tons of other things extension methods would be useful
for. I think once you had them, you'd wonder how you ever lived
without them. For instance, you'll immediately be able to say:

import java.util.List;
import static java.util.Collections.sort extends java.util.List;

List things;
things.sort();

Wouldn't that be nice?

It's just an alternate syntax for calling a static method. And yes,
if you're going to allow that it would be nice if everyone could play,
not just the author of the interface. But without it you could still
write their more complex example as

import static Collections.filter;
import static Collections.map;
import static Collections.reduce;

int ans = reduce(map(filter(s, #(int x)(x != 0)),
#(int x)(x + 3)),
#(int x, int b)(x + b), 0);

This isn't quite as nice as the extension method syntax but it still
isn't too bad. And if you switched the order of the arguments to put
the collection last it could be

int ans = reduce(#(int x, int b)(x + b), 0,
map(#(int x)(x + 3),
filter(#(int x)(x != 0), s)));
 
L

Lew

Ken said:
Begging your pardon, but the Mayan calendar ends in only two years. I
have my doubts whether we'll have a released Java 7 by then, let alone 8.

I said "due", not "guaranteed" or "likely".
 
A

Andreas Leitgeb

Tom Anderson said:
The terseness lends itself to the typical higher-order-function uses,
like:
List<String> names;
List<Integer> lengths = names.collect(#(String s) (s.length()));

I seem to have missed one part of the ("straw man") proposal. Is there any
mention of checked exceptions? Are they just plain forbidden, or is
there some extra syntax for specifying those with lambdas?
Given that we won't be able to add lambda-aware methods to existing
collection interfaces, because that would break all existing code which
implements them, extension methods are the only way of being able to write
the example i give above,...

I don't quite understand the benefit of those particular extension methods.
My impression is, that once the train leaves its current station "single
inheritence and multi interfaces", there won't be any useful stop before
"multi inheritence". Extension methods look to me just like an extra stop
in the suburbs of "multi inheritence" town, where most of the downsides (like
the much more complicated method-resolution) are already pressing, but most
of the uses are deliberately withheld. What's the benefit of deferring to
a separate static method as opposed to implementing the default directly in
the same interface?
Also, i really don't like the implicit function conversion. [...]

Not doing it that way now, will likely lead to it being added later as a
syntactic sugar to remove the highly redundant boilerplate idiom
new MySAMInterface() { public RetType sm(ArgTypes a) { return lambda(a); } }

How do you feel about the other direction, allowing appropriate SAM-class's
instances to be passed for lambda-arguments?
 
A

Arne Vajhøj

Begging your pardon, but the Mayan calendar ends in only two years.

From what I can wiki'e then the Mayan calendar does not
end in 2012 - it just starts a new 5125 year cycle.
I
have my doubts whether we'll have a released Java 7 by then, let alone 8.

They should have cut enough out of 7 to make it ship.

Arne
 
M

markspace

On 15-11-2010 22:19, Ken Wesson wrote:

From what I can wiki'e then the Mayan calendar does not
end in 2012 - it just starts a new 5125 year cycle.


Yes, and only then because they ran out of digits. And I forget if
that's the long calendar or the short one. They lobbed off some digits
(pictograms) at some point because their dates were just too long to
carve into the sides of pyramids all of the time.
 
L

Lew

You have to go and mess up a perfectly good "sky-is-falling" urban legend with
facts.
Yes, and only then because they ran out of digits. And I forget if
that's the long calendar or the short one. They lobbed off some digits
(pictograms) at some point because their dates were just too long to
carve into the sides of pyramids all of the time.

What are they in, base 41?
 
S

Stefan Ram

markspace said:
Yes, and only then because they ran out of digits.

This shows that there /is/ real progress in our world,
because today we have UNIX time that will last until even
2038. And then think of the height of progress mankind
finally reached after more than 2000 years of research:
*java.util.Calendar*.
 
C

ClassCastException

This shows that there /is/ real progress in our world, because today
we have UNIX time that will last until even 2038. And then think of
the height of progress mankind finally reached after more than 2000
years of research: *java.util.Calendar*.

Ye gods. If this is progress, I'd hate to see backsliding. (Maybe
something like the date type in some demon-inspired cross between Visual
Basic and COBOL, in Roman numerals, counting backwards from 39704? Oh no.
I had to say it! Now someone will implement it and mandate it for all
office work as part of ISO9002 or something.)
 
M

markspace

What are they in, base 41?


I don't think they actually used a number base. It was more like Roman
numerals, where each "digit" actually reprints some increasing larger
amount of time, though not always a regular increase. They had "digits"
representing 1, 20, 360, 720, and 144000 days. There where higher order
"digits" too, but I'm not aware of what they represented.
 
M

Martin Gregorie

Ye gods. If this is progress, I'd hate to see backsliding. (Maybe
something like the date type in some demon-inspired cross between Visual
Basic and COBOL, in Roman numerals, counting backwards from 39704? Oh
no. I had to say it! Now someone will implement it and mandate it for
all office work as part of ISO9002 or something.)
UNIX had 32 bit time variables, hence its epoch was tiny: 68 years
(1970-2038). This is the shortest date range of any OS I've used.
Fortunately its since been upgraded to 64 bits, so the UNIX epoch will
now outlast the universe with a healthy margin for error.

Cobol, too used to have a century long epoch, mainly because you could
only accept a six digit date: yymmdd. Now that's been extended to eight
digits by adding a two digit century, so the epoch ends in the 100th
century. That's probably more than enough to outlast humanity at the rate
we're going.
 
L

Lew

Martin said:
Cobol, too used to have a century long epoch, mainly because you could
only accept a six digit date: yymmdd. Now that's been extended to eight
digits by adding a two digit century, so the epoch ends in the 100th
century. That's probably more than enough to outlast humanity at the rate
we're going.

But not to outlast the use of COBOL.

:)
 
M

Martin Gregorie

But not to outlast the use of COBOL.
Indeed, and also why IBM heavy iron still presents the same 1960s
System/360 programming environment to native programs. Some of those
large and complex late 60s applications are still alive and well and
running in banks and airlines, quite possibly because nobody now
understands them well enough to re-implement their core functions.
Documentation gets out of date and, if binary patching was used in that
shop, the program source may not match the binary code.

BTW I have a sneaking suspicion that the Y2K bug can be traced back to a
combination of early IBM kit (both mainframe and PC) that only dealt with
6 digit dates and the Cobol ACCEPT verb which had the same limitation
until (I think) 2002 at the earliest.

If we'd all been using ICL 1900s, or at least the same date
representation, Y2K would have never been a problem: those machines held
dates as days since 31 Dec 1899 (i.e. 1 Jan 1900 was day 1) in a signed
24 bit word, so its Y2K would have occurred toward the end of the 46th
century.

IMO the major factors were leading to Y2K were:
- when your OS and programming language both mandate yymmdd, you need
to be a considerably better than average system designer or have
a requirement that mandates a huge date range[1] to think far enough
outside the box to even realise there's likely to be a problem in 10
to 20 years time.

- in the 70s and early 80s many in-house applications had a lifetime of
5-10 years before being rewritten from scratch. I remember designing
a tape library database that potentially had a very long life indeed
(how long does a carefully stored audio tape last?) and being totally
unable to extract an expected life from its sponsors. In the end
the best I was able to do was to size the database for 10 years of
recordings and build in warnings of impending doom and a soft fail if
nobody had done anything to allocate more space.

[1] the Radio 3 Music Planning system, which handled an astounding range
of date formats (exact date, and a variety of fuzzy dates) and from BC
into the future. Euripides wrote a song in 55BC whose words if, not
music, were still extant. The inexact dates were needed because often a
composer's dates aren't known at all well, hence '13th century' and
'flourished 1530' as well as just a year: 'The Song of Roland' was a
minstrel hit written in 980.
 
T

Tom Anderson

From what I can wiki'e then the Mayan calendar does not end in 2012 - it
just starts a new 5125 year cycle.

It's worth mentioning that this is not a top-level cycle: the digit that
is rolling over is the fifth up; there is some evidence that the current
date has 24 digits.

I don't think they actually used a number base.

They did - base 20. With the quirk that the tens-place digit is base 18.
So, using an extension of hexadecimal to vigesimal like:

1111111111 denary tens
01234567890123456789 denary units

0123456789abcdefghij vigesimal

the count goes:

i // 18
j // 19
10 // 20
11 // 21
....
hi // 358
hj // 359
100 // 360
101 // 361
....
jhi // 7198
jhj // 7199
1000 // 7200
1001 // 7201

It seems some people think that this was so a year would have about 100
days. This is not entirely convincing to me.
It was more like Roman numerals, where each "digit" actually reprints
some increasing larger amount of time, though not always a regular
increase. They had "digits" representing 1, 20, 360, 720, and 144000
days. There where higher order "digits" too, but I'm not aware of what
they represented.

No, they absolutely had a digital system.

http://en.wikipedia.org/wiki/Maya_numerals
http://en.wikipedia.org/wiki/Mesoamerican_Long_Count_calendar

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top