--
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.
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/AdDk0G2vp1UJ.
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.
The problem being that the local environment for the function you are
in in Java gets destroyed when you return from the function. The
compiler will copy over final values into the new environment that you
create with an anonymous class, but the environment that exists as you
create this instance gets destroyed. (Hence, requiring that any
variables exposed to the "closure" be final.)
That is, if we had true closure (even without first order functions),
you could declare two of them that communicated through a mutable
variable. Correct? (This is a legitimate question, not a rhetorical
trick.)
The problem being that the local environment for the function you are
On Sep 12, 4:05 pm, Cédric Beust ♔ <ced...@beust.com> wrote:Is this the point in the conversation where we hit Turing-
> Jave has indeed had closures since day one (e.g. Runnable, Callable,
> etc...). If you're not convinced, ask yourself the following question: is
> there any programming construct that you will be able to do in Java 8 with
> closure support that you can't do today with Runnable?
completeness?
Syntax is terser (nicer, I'm not so sure I'm willing to absolutely
> None.
>
> The syntax will be nicer, but that's all Java 8 is adding in that area.
commit to that) than 1.1, but there is also an alleged lighter
implementation available with method handles (alleged as the
optimisation may perhaps be harder and heavier).
Tom
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
So, make a 2 closures and then alternate calling each where the first
increments an int, and the second prints it.
That is,
public void foo() {
int myInt = 0;
Runnable a = new Runnable() {
public void run() {
myInt++;
}
};
Runnable b = new Runnable() {
public void run() {
System.out.println(myInt);
}
};
a.run();
b.run();
}
If we had closures, you could do this, no? (Again, not being
rhetorical. This is just how I understand the situation.)
Java doesn't have closures in the way most people think of closures.
It has closures in a half-assed, un-friendly way. So people don't use
them much and in effect, Java doesn't have closures.
And people use them quite a bit in more recent libraries because many
people are trying to pull over some really good ideas from other
places.
>> javaposse+...@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.
>> 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.
> 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.
Not sure who you're saying is a pedant in this conversation, but I would have to say that despite Java's closures not being really closures, people do use them quite a bit. See the style of GWT API and Guava for a few good examples.
This breaking news, just in: C has objects, and Lisp has static types.
More details to come as events unfold.
1. "foobar" is a language construct that either is the same thing of a
closure or a subset of a closure
2. foobars are useful for programmers
3. the difference between a foobar and a closure, if any, is neglectable
from a practical point of view
4. Java has always had foobars, in form of SAM classes
5. Java 8 provides a nicer, shorter syntax for foobars
I think that points 1, 2, 4, and 5 are quite obvious and I suppose
nobody disagrees. So, the important point is #3. If you can't
demonstrate that point #3 is false, then clay and C�dric might be not
pedantic enough from a semantic point of view (not my business), but are
substantially right.
--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
Kevin,
In reading the entries for this thread, I was at a loss as to where to
dive in. Thanks for providing a cue!
C++ prior to C++11 has what is effectively closures in that you can
create instances of classes with an operator ( ) overload and ensure
that the constructor requires parameters such that an instance of the
class has no free variables. This technique has now been folded into
the lambda functions introduced in C++11 and given a specialist syntax
so people don't have to roll their own.
Java not allowing operator overloading makes this just a tiny bit more
verbose: you have to call the function call or something. Nonetheless
the same programming idiom applies.
The issue here is the difference between "infrastructure that allows"
and "syntax that represents". Having "syntax that represents" is a
raising of the abstraction level that means (generally) that the
language is easier for programmers to write good programs. Clearly
there are counter-examples, but the point remains.
--
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
I already did. Here, spot the closure in Scala:
def printNumbers(max:Int) {
for( x<- 1 to max) {
println(x)
}
}
It isn't enough that the closure could get a copy of x from the
environment, it has to capture mutations to it, as well. Can you
accomplish the same thing with other means? Of course. (And,
someone please correct me if I am wrong on this.)
> I can articulate exactly why C doesn't have real objects. You can do
> OO style programming in pure C, and you design your code as "objects"
> in the conceptual sense, but you don't have language level support for
> it.
I articulated exactly what would be necessary for Java to have
closures. That you think it counts to modify the program to use
different objects shows that you aren't actually getting the argument.
This would be like saying Java has "pass by reference" because I can
do the following:
public void swap(Foo a1, Foo a2) {
Foo tmp = new Foo(a1);
a1.setValuesFrom(a2);
a2.setValuesFrom(tmp);
}
Sure, you can "swap" elements in this way. But this is not what pass
by reference means.
I'm sympathetic to both arguments. Hell, I incorrectly call java pass
by reference all the time. I get called on it and sometimes I try and
backpedal what I meant and claim I was correct. The fact is that it
is not pass by reference, no matter how well I know what I meant to
say, to claim otherwise is wrong.
And this is ignoring the fact that anonymous inner classes have not
been there since day 1.
I'm not the O.P, but I'll take a swing:
"Full" Closures capture the lexically scoped *variables* at the time
of closure creation. Changes the closure later makes to those
variables when it is run will be visible to any other closure that has
captured those same variables. (Let's call this "communication by
mutation".)
Java's anonymous inner classes copy the *values* bound to lexically
scoped variables at the time of object instantiation. You can achieve
up "communication by mutation" by an additional level of indirection:
just let your variable hold a reference to something that is mutable.
In languages where variables are immutable, such as Clojure, this is a
distinction without a difference.
The fact that Java's AIC only copy values and don't capture variables
is something I don't lose sleep over since I try to avoide mutability
where I can.
// ben
I offered that I am the one being pedantic. :) How do you feel about
whether or not java has "pass by reference?" For those that care that
objects are not copied to the stack, the fact that you can not write a
swap is likely a splitting hairs argument, as well. (For those that
care about the swap, it is key.)
And, yes, I have had several times when I would have liked to do something like:
for (int x = 0; x < count; x++ ) {
new Runnable() { public void run() {someFunctionOn(x);}}.run();
}
This would require a closure. A function literal would help, but a
closure is necessary to make it work.
> I'd still say that the language level limitations that are holding
> Java back from a more functional programming style isn't the "final"
> variable restriction of Closure like functionality, but the lack of
> first class functions and a more concise anonymous function syntax.
> And, ideally, Java would have a standard collections library with
> persistent immutability support (like Scala's collections).
>
I don't disagree. What you are describing, though, sounds like you
really should jump ship to one of the alternative languages. Not
because java sucks, but because other languages have what you want.
I think you'd be surprised by how often there is confusion over this
very point. :) (Granted, I think some of the escape analysis tricks
whereby scaler replacement happens just throws a giant wrench at this
one. I may be horribly abusing these terms.)
> With Closures, there is a lot of confusion. Java has something
> extremely close to closures, and only a real pedant can debate the
> distinction. I also think when people say that Java lacks closures,
> they are referring to first class functions and concise anonymous
> function syntax instead.
I don't disagree that most people are more concerned with function
literals than they are closures. Doesn't change the fact that Java
doesn't have closures.
> For your loop example, can't you simply do:
There are many different ways I could have done that differently. I
wasn't off to produce a program that you could not do in Java. I
simply was showing what Java could do if it had closures. Much like I
can quite confidently say you can not write the following java
program:
public void addSomeMatrix(Matrix a, Matrix b) {
return a + b;
}
Of course you can represent the same thing with a.plus(b) most likely.
This gets ugly as sin if you are trying to move an algorithm into
java but want to use BigDecimal, for example.
"This breaking news, just in: C has objects, and Lisp has staticRather than all the snarky replies, how about you actually explain
types."
what makes the Closure-like functionality in Java not really true
closures?
I can articulate exactly why C doesn't have real objects. You can do
OO style programming in pure C, and you design your code as "objects"
in the conceptual sense, but you don't have language level support for
it.
People say "Java doesn't have closures" so frequently that people
believe it. But it is really just a common misuse of terminology. What
(I think) people mean, when they say that, is that Java doesn't have
first class functions (functions as objects) and a concise anonymous
functions syntax. But, closures is a feature that Java has always had.
I'm not trolling, I'm just trying to get the labels and terminology
accurate and clear.
for (final AtomicInteger x = new AtomicInteger(0) ;
x.intValue() < 10; x.incrementAndGet())
{
new Runnable()
{
@Override
public void run()
{
System.err.println(x.intValue());
}
}.run();
}
--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
fabrizio...@tidalwave.it
http://tidalwave.it - http://fabriziogiudici.it
The example
using System;
delegate void D();
class Test
{
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}
static void Main() {
foreach (D d in F()) d();
}
}
produces the output:
1
3
5
However, when the declaration of x is moved outside the loop:
static D[] F() {
D[] result = new D[3];
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}
the output is:
5
5
5
--
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.
People don't use closures in Java that much? I emphatically disagree.
I completed writing a JavaFX 2 application in Java: Every single
button handler or GUI event handler uses an anonymous class wrapped
around a function, and most of those access local or instance
variables from the defining scope, where my coworkers and I refer to
it as a closure. The Swing and GWT APIs are also designed for heavy
use of anonymous functions and closures (most Java server side web
frameworks don't use anonymous functions at all). We also do the same
thing in our (non Java) JavaScript client code and we call them
closures there as well.
No, I'm really not being pedantic. I use closures so extensively in
Java, it is ridiculous to say that they don't exist. That's like
telling me Java doesn't have a for loop or exceptions.
I'm not sure what myth I was using that you debunked. :( The example
I gave is a full closure where one wouldn't even realize a "lambda"
was being used in most cases. In fact, I'm not sure how you would
provide a full function to a for comprehension that referenced
variables without a full closure.
> You can't spot the closure in that Scala code because closures are not
> syntax. They are an implementation mechanism provided by compilers. The
> term we should have been using all these years is lambdas, which is what
> Haskell, Lisp and C# call it. And that's what Java doesn't have; a syntax
> for lambdas. It instead has a syntax for anonymous classes, which can be
> used to emulate lambdas, and pretty well.
I have agreed there is a difference between function literals
(lambdas) and what a closure is. I have even ceded that I am being
pedantic.
The rest of your post seems to just be saying "if we change the
definition of closure, then Java has them."
That is, you seem to be claiming that java 1.3 had varargs because you
could have written the method:
String.format("%s", new Object[] { someObject });
This is just a minor inconvenience over the new syntax that allows
varargs, but that small change means everything. Same goes for
function literals. I confess that I can not think of too many places
where I would miss full closures. About the best I can think is in a
for comprehension style thing, where you can drop the necessity for
determining all of the arguments that the inner "lambda" needs, as it
can just capture the surrounding variables. And, as pointed out, you
could just move the indirection to the object being held. (Not sure
this really looks any better at all.)
Continuations are a powerful concept. Scheme demonstrates that they
can be powerfully combined with closures. But, it seems to me that
closures and continuations are separable concepts. I don't think
mixing the two concepts helps to clarify things.
That said, the earlier BBGA closure proposal touched on three points:
(1) closures
(2) function types
(3) control abstraction similar to what's shown by the examples in the
linked article (implying a limited kind of continuation support under
the covers.)
What's planned for JDK8 is only #1, where SAM plays the role of #2,
though they say they are leaving the door open for introducing #2 at
some point in the future.
// Ben
> javaposse+...@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.
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/53VocU4KYT0J.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
I think the problem is that whenever you start trying to make sure that all code wrapped in a lambda behaves the same as code not wrapped in a lambda (return, break, this, continue, throw all behaving the same way) you get into odd territory and someone picks up on it and reacts.
To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/Fff1UZB3f5EJ.
--
Skype: ricky_clarkson
--
Skype: ricky_clarkson
To post to this group, send email to jav...@googlegroups.com.
To unsubscribe from this group, send email to javapo...@googlegroups.com.
Just lifting the variable to a field means you have completely moved
the memory semantics of it. Suddenly "volatile" is a relevant
modifier of a local variable. Well, some of them. :) (Right?)
Just lifting the variable to a field means you have completely moved
the memory semantics of it. Suddenly "volatile" is a relevant
modifier of a local variable. Well, some of them. :) (Right?)
To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/W8qWzFi4XtoJ.
I disagree that the C# example is contrived, having accidentally made the mistake they show.
--
Skype: ricky_clarkson
--
Skype: ricky_clarkson
To unsubscribe from this group, send email to java...@googlegroups.com.
--To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/Fff1UZB3f5EJ.
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to jav...@googlegroups.com.
To unsubscribe from this group, send email to javapo...@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.