The Artima Developer Community
Sponsored Link

Java Community News
Closures without Complexity

9 replies on 1 page. Most recent reply: Oct 17, 2006 3:06 PM by Dave Brosius

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 9 replies on 1 page
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Closures without Complexity Posted: Oct 11, 2006 11:26 AM
Reply to this message Reply
Summary
The most recent proposal by Josh Bloch, Doug Lea, and Bob Lee in the ongoing debate on closures in Java suggests a more relaxed syntax for inner classes, and to no longer require variables accessed by inner classes to be final.
Advertisement

Introducing true closures into Java has been the subject of heated debate lately. The latest contribution to this discussion is a proposal by Josh Bloch, Doug Lea, and Bob Lee, Concise Instance Creation Expressions: Closures without Complexity. The pair notes that:

Since release 1.1, Java has had closures in the form of anonymous class instance creation expressions ... that extend a class or interface with a single abstract method. We call such classes and interfaces single-abstract-method types, or SAM types for short... The resulting closures are often used to parameterize the behavior of collections (e.g., a Comparator specifies the order of a SortedSet), and to submit code for concurrent execution (e.g., a Runnable may be executed by a Thread or an Executor). Unfortunately, the verbose and ungainly syntax of anonymous class instance creation expressions frustrates programmers...

They propose to make working with SAMs easier:

The basic idea is to omit the keyword new, the class declaration, and the method name from class instance creation expressions... For example, here is the Java 5 code to start a thread whose run method invokes a method named foo:

 
new Thread(new Runnable() {
    public void run() {
        foo();
    }
}).start();

If we adopt this proposal, the following code would be equivalent:

new Thread(Runnable(){ foo(); }).start();

Bloch and Lea term the proposed construct "concise instance creation expression" (CICE), noting that "you can use a concise instance creation expression everywhere that an instance creation expression is currently legal."

Bloch and Lea's proposal also addresses the oft-mentioned developer gripe of having to declare final any variable accessed form an anonymous inner class:

We propose making such variables final by default. Programmers also complain that instance creation expression method bodies are not permitted to share mutable local variables with the enclosing scope. Therefore, we further propose allowing such access if the local variables in question are explicitly declared public.

Here's an example of the "annoying final" in Java 5. This method takes a comparator and returns a comparator that induces the reverse ordering:

static  Comparator reverseOrder(final Comparator cmp) {
    return new Comparator() {
         public int compare(T t1, T t2) {
            return cmp.compare(t2, t1);
         }
    };
}

Here's how the method would look if this proposal were adopted:

static  Comparator reverseOrder(Comparator cmp) {
    return Comparator(T t1, T t2){ return cmp.compare(t2, t1); };
}

Of all the recent proposals to add true closure support to Java, Block and Lea's sounds rather reasonable, because it would actually simplify current syntax by making a set of assumptions based on current practice.

What do you think of the Bloch and Lea's proposal?


Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: Closures without Complexity Posted: Oct 12, 2006 5:28 AM
Reply to this message Reply
I do not like the proposed solution very much, for these reasons:

1) not having to use 'new' to create a new instance will introduce yet another point of confusion for Java users. It only takes 3 keystrokes anyway, and I do not see what the big deal is.

2) the syntax that moves the method parameters to the class level is ugly and confusing. Suddently the very real distinction between a class and a method is removed and the two concepts are blurred.

3) the proposal introduces a new rule which applies to interfaces/classes with one method only; but there are numerous interfaces/classes in the SDK and in other libraries that have more than one methods to overload. Remember that one of C++'s disadvantages is that there are many exceptions to the rules to remember, and even those exceptions have their own special cases.

4) the final keyword is not really needed. Variables accessed from within closures should be members of a heap allocated block created at method invocation; these blocks should contain only the 'local' variables that must remain into existence after the method returns.

What I would like to see in Java is delegates and events, like in C#. It really makes a difference to be able to do this:

bar.action += foo.action;

Marcin Kowalczyk

Posts: 40
Nickname: qrczak
Registered: Oct, 2004

Re: Closures without Complexity Posted: Oct 12, 2006 7:26 AM
Reply to this message Reply
Too little, too late.

Compare the syntax of examples on that page, with the real syntax of another language, which happens to not even need closures in these cases:
Thread foo

ls->SortBy Size

or with the second example translated more literally:
ls->Sort ?s1 s2 {Size s1 < Size s2}

The restrictions of final variables are silly. There is no semantic difficulty in making mutable variables accessible to local functions. But this design makes an even uglier twist, where a variable referenced from local functions is automatically final unless overridden by an overloaded public. This complication is completely unnecessary, making mutability of a variable dependent on where it is referenced from is evil. All variables should be accesible from their scope, period.

I avoid Java because its designers like inventing new ways to add pointless restrictions, to make programming less pleasant. The family of proposals of restricting accessibility of local variables to nested functions in various ways is a perfect example of that.

Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: Closures without Complexity Posted: Oct 12, 2006 8:33 AM
Reply to this message Reply
After posting about this proposal, Cedric Beust has kindly informed us that Bob Lee (http://crazybob.org) also participated in formulating this proposal. We made this correction to the post—sorry, Bob, for leaving your name out in the first place.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Closures without Complexity Posted: Oct 12, 2006 7:32 PM
Reply to this message Reply
YUCK!

More magic syntax. It leaves the single method name omitted and implicit. I dislike magic and this looks like a triangular peg in a slotted opening.

Most hideous.

Abhijit Akhawe

Posts: 4
Nickname: abhi27
Registered: Oct, 2006

Re: Closures without Complexity Posted: Oct 14, 2006 2:06 PM
Reply to this message Reply
The CICE concept though good is just a cosmetic change. And though its intention is good I am sure the language syntax will become quit complicated. Same is the case with auto-final for variables.

Besides the changes hardly answer the question about how to implement closures in JAVA? If we are to continue with using inner classes for closures we might as well continue them with their current syntaxes. Afterall a Ctrl+1 in eclipse does it all for you!

I can already see the JCP exam designers thinking of ways to devise freaky questions with the new syntax ;)

francis mok

Posts: 1
Nickname: fcmmok
Registered: Oct, 2006

Re: Closures without Complexity Posted: Oct 16, 2006 8:31 AM
Reply to this message Reply
hi,

A very important concept:

'Delegate or method reference or method pointer' is not equal to 'closure'.

This is a method reference/delegate:


bar.action += foo.action;


Ans this is a closure:


bar.action = (int x){return x + 2};


although they look similar, but they are completely different things.

Eirik Maus

Posts: 15
Nickname: eirikma
Registered: Oct, 2005

Re: Closures without Complexity Posted: Oct 17, 2006 1:49 AM
Reply to this message Reply
> <p>What do you think of the Bloch and Lea's proposal? </p>

Horrible!
It is way more magic than the first suggestion.

I think the start of the first suggestion was good, but they took it a little too far perhaps. This new approach is too simliar to the existing while still resulting in new behaviour. Actually, it is identical to errors made by fresh students who don't understand the distinction between classes and objects yet. I don't see the point in turning beginners' errors into code that works and maybe does something that is vaguely related to what the student intended.

I really can't understand why this has to be that difficult. Simula allowed method signatures to appear in a method parameter list. The caller could invoke a method that had a method parameter just like a normal method, using the name of the closure method in the invocation. The called method can not "save" the method reference, since Simula (like Java) have no method reference types. It could invoke the closure method as a normal method call.

It would look like this (generics omitted):
// declaration
class SomeCollection implements java.util.Collection {
   // ....
 
   /** method with method parameter */
   Collection filter(boolean includeObject(Object o)) {
     Collection retval = new SomeCollection();
     for (Object o: this) {
       // use closure method passed in
       if (includeObject(o)) {
           retval.add(o);
       }
     }
     return retval;
   }    
}
 
class User {
  
  private boolean isJohnDoe(Object o) {
     return ((User)o).getName().equals("John Doe");
  }
 
  public static void main(String[] args) {
     SomeCollection sc = new SomeCollection();
     // ...
 
     // invoke by naming method to transfer as closure
     // no parameters to the closure method here, 
     // since it is not invoked _here_ but in the 
     // receiving method. 
     Collection johnDoes = sc.filter(isJohnDoe);
  }
}


Perhaps I'll write a suggestion myself.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: Closures without Complexity Posted: Oct 17, 2006 9:39 AM
Reply to this message Reply
> hi,
>
> A very important concept:
>
> 'Delegate or method reference or method pointer' is not
> equal to 'closure'.
>
> This is a method reference/delegate:
>
>
> bar.action += foo.action;
>

>
> Ans this is a closure:
>
>
> bar.action = (int x){return x + 2};
>

>
> although they look similar, but they are completely
> different things.

C# 2.0 blurs the concept in an appropriate manner:


bar.action += function(int x){ return bar.x + x; }

Dave Brosius

Posts: 3
Nickname: dbrosius
Registered: Jun, 2006

Re: Closures without Complexity Posted: Oct 17, 2006 3:06 PM
Reply to this message Reply
Seems like a lot of histrionics for very little benefit. Is the concept of 'final' really keeping people up at nites? My vote is thumbs down.

Flat View: This topic has 9 replies on 1 page
Topic: Closures without Complexity Previous Topic   Next Topic Topic: Joe Darcy on Standardizing Annotation Processing

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use