What I perhaps didn't make clear is that I'm talking about taking some code
that's part of a method, and then making it part of a lambda within that
method.
E.g., in some imaginary syntax:
void foo() {
if (Math.random() < 0.5)
return;
System.out.println("Foo");
}
void foo() {
timeHowLongThisTakes( () => {
if (Math.random() < 0.5)
return;
} );
System.out.println("Foo");
}
Return is one example; others are break, continue and throw. The meaning is
not kept if you wrap that code into a new Runnable() { public void run()...
}
Gafter's original, well thought-out, argument was that wrapping code in a
closure should not affect its meaning, which makes a lot of sense, but the
actual mechanisms needed to do that at least before engaging the VM team are
odd, it used exceptions under the hood to manage these things, and there
were objections to that. And (answered) questions about what return; would
mean if the lambda were to be executed on a different thread to the
surrounding method.
I think at this stage it makes sense to stick with a restricted lambda and
get that in stone. The current proposal does not in any way preclude Oracle
from adding support for capturing mutable variables, a notation for outer
returns, enabling break and continue, and making throws able to be
transparent.
Regarding mutable variables, I'm sure you read the passage I quoted from the
C# specification and can appreciate that it's not all roses without that
limitation. It's not just theoretical, in my brief time on Freenode's
##csharp I noticed it appeared fairly often. Whether it was deliberate 14
years ago I don't think matters any longer.
--
Skype: ricky_clarkson
On Wed, Sep 14, 2011 at 11:12 PM, opinali <[email protected]> wrote:
> On Wednesday, September 14, 2011 9:15:30 PM UTC-4, Ricky Clarkson wrote:
>>
>> 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.
>
>
> This seems to be mixing things. Code inside an inner class certainly
> behaves exactly like all other code; specifically, you can define mutable
> variables and you can assign to these variables. So the typesystem inside
> the "closure" is exactly the same. Which in this case, makes inner classes
> even more broken, it would be cleaner if inner classes had been designed as
> a pure-functional subset of the language that couldn't do destructive
> assignments at all.
>
> See Guy Steele's comments about inner classes:
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg04044.html -
> Java was initially planned to have closures, including mutable capture, but
> that was cut from JDK 1.0 and when they introduced inner classes in 1.1, it
> didn't have mutable capture and the reason was just "users feared the
> performance cost" - maybe reasonable concern with JDK 1.0's VM with the
> crappiest GC ever, but an obsolete issue since HotSpot, not to mention that
> other language features already ignore any concerns (performance or other)
> of implicit allocations, like Steele points. Also, James Gosling referred to
> inner classes as an `"uncomfortable compromise ... that didn't really solve
> any problems": http://blogs.oracle.com/jag/entry/closures. And a third
> "father of Java", Bill Joy, also wanted full support for closures since day
> one: http://www.blinkenlights.com/classiccmp/javaorigin.html
>
> TL;DR: The mutable capture limitation of inner classes was NOT introduced
> by design. Not one of the original Java designers are proud of inner
> classes. Any attempt to justify this limitation as something that makes
> sense with good language design principles, is rewriting history - "it's not
> a bug, it's a feature".
>
> A+
> Osvaldo
>
>
>
>>
>> Scala actually does some* of what Gafter's original proposal did regarding
>> control, and the reality is I've only ever noticed when I explicitly tested
>> it to see if I could observe a NonLocalReturnException. However, I don't
>> think we're going to win that fight, and C#'s level of lambda support really
>> is a marked improvement over what we have in Java today.
>>
>> * some, because Scala doesn't have continue or break.
>>
>> --
>> Skype: ricky_clarkson
>>
>>
>> On Wed, Sep 14, 2011 at 8:38 PM, opinali <[email protected]> wrote:
>>
>>> Hi clay,
>>>
>>> Ok let's be more formal now. I agree with option A below (instead of B);
>>> "closure" is very well defined in numerous classic CS books as the pairing
>>> between a function and an environment that provides bindings to its free
>>> variables. The concept comes from lambda calculus where functions can only
>>> exist in the form of functions, so I understand view B - but practical
>>> programming languages are very distant from pure lambda calculus; only in
>>> the Lisp family (I think) they are really the same because functions are
>>> just sugar for a lambda - i.e. a function is a lambda that is bound by some
>>> name to some environment. But there are many other languages, including
>>> Java, where this doesn't happen, unless you interpret the concept of
>>> "environment" as something more general, including the all scoping rules,
>>> classloaders, etc. IMHO this is going a bit too far, I'm happy with a
>>> definition of closures that does not depend from lambdas.
>>>
>>> Now back to my points 1/2, let's try to refine the discussion to its true
>>> essentials: the major point of debate is whether Java's closures (with or
>>> without Java 8's lambdas) are "good enough". So let's try to define what
>>> constitutes good enough. I am a strong advocate of very powerful closures; I
>>> was rooting for BGGA with its non-local returns, control abstractions...,
>>> but I concede that these features are only necessary to extend Java's
>>> paradigm, allowing significant new idioms. But it's fair to require for
>>> "good enough", an implementation of closures that is at least sufficient to
>>> get along with the *existing* language paradigm, idioms and other features
>>> (typesystem, OO model etc.) - anything better that that is a bonus. If we
>>> agree on this, then "good enough" boils down to orthogonality. And the
>>> current support for closures (without capture of mutable variables) is
>>> clearly NOT orthogonal, because destructive assignment is a HUGE part of the
>>> Java language. No amount of fancy functional-esque frameworks or conventions
>>> can change this simple fact. It's broken since JDK 1.1's introduction of
>>> inner classes, and it will be broken in Java 8's even with lambdas, nice
>>> syntax, and tons of new or retrofitted APIs to use closures/lambdas.
>>>
>>> A+
>>> Osvaldo
>>>
>>>
>>> On Tuesday, September 13, 2011 7:58:02 PM UTC-4, clay wrote:
>>>>
>>>> From the best I can gather, the principle disagreement is definitions.
>>>> There are three views in this thread:
>>>>
>>>> A) Java has closures. Closures, by definition, do not necessarily
>>>> require lambdas or first class functions, which Java doesn't have.
>>>> B) Closures, by definition require lambdas and/or first class
>>>> functions, so since Java doesn't have those, it can't have closures.
>>>> C) Pure closures, by definition, don't limit you to accessing only
>>>> "final" variables, so the anonymous class functionality doesn't
>>>> qualify as a closure.
>>>>
>>>> Osvaldo,
>>>>
>>>> Regarding point #1: First, I think you mean anonymous classes, not
>>>> inner classes. Secondly, I'd stress that anonymous functions (lambdas)
>>>> are a distinct feature from closures. A language can have one feature
>>>> but not the other. Java has closures, but not lambdas. And I can't
>>>> think of them off the top of my head, but I'm sure there are languages
>>>> with lambdas that don't close over the defining environment, and
>>>> therefore don't have closures.
>>>>
>>>> Regarding point #2: I'm not sure what you are getting at here. Sure,
>>>> Java is behind the pack in terms of immutable programming and
>>>> functional programming support, but you can use third party libraries
>>>> like Functional Java and adopt that style as a programmer. Only a few
>>>> languages like Haskell really force those concepts on you and
>>>> guarantee safety from mutability issues. In Scala, immutable code and
>>>> functional programming still requires programmer compliance and it's
>>>> easy to write imperative mutable code. Regardless, this seems like a
>>>> tangential issue.
>>>>
>>>> Kevin,
>>>>
>>>> I'm not arguing that Java has closures because you can achieve the
>>>> same goals without real language level support. I'm arguing that
>>>> closures are inner functions/methods that can access variables from
>>>> the outer function/method scope, and the Java language syntax
>>>> completely supports that. You are claiming that closures require
>>>> lambdas by definition, and I disagree with you on that definition.
>>>> Java doesn't have lambdas. Sure, you can achieve similar results with
>>>> anonymous classes, but the Java language itself doesn't provide
>>>> lambdas.
>>>>
>>> --
>>> 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<https://groups.google.com/d/msg/javaposse/-/53VocU4KYT0J>
>>> .
>>>
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected]**.
>>>
>>> For more options, visit this group at http://groups.google.com/**
>>> group/javaposse?hl=en <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/-/Fff1UZB3f5EJ.
>
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> 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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/javaposse?hl=en.