The Source for Java Technology Collaboration


Closures Syntax in Java 7

There is a proposal floating around by Gilad Bracha, Neal Gafter, James Gosling, and Peter von der Ahé on adding support for closures to the Java language in the Java 7 release.

PDF with proposal draft

This page is to collect

  • links related to the proposal
  • commentary on the proposed syntax
  • samples of how the syntax would look

Links

Proposal

Blogs

Discussions

Syntax: Samples of Possibilities

This section captures samples of possible syntax using closures. As seen in Neil Gafter's blogs, the proposed syntax (deriving from the original PDF) is being reworked and in some cases, simplified. The syntax shown here may not be what is actually used in a final implementation. Note that Gafter has also indicated there is more than one proposal for closures floating around (at Sun?) and that no decision has been made about whether it will be done or it what form.

Anonymous Inner Classes

One use-case for closures is to reduce the need for anonymous inner classes. The following is from Neil Gafter, in Neil Gafter's Blog: Use cases for closures. As Neil puts it, If this syntax doesn't mean anything to you, just imagine that the block appearing at the end of the invocation of ex.execute is turned into a closure and then passed as the last argment (the only one, in this case) to execute. That's basically what the abbreviated invocation syntax does.

Syntax without closures

void sayHelloInAnotherThread(Executor ex) {
    ex.execute(new Runnable() {
        public void run() {
            System.out.println("hello");
        }
    });
}

Closure Syntax

void sayHelloInAnotherThread(Executor ex) {
    ex.execute() {
        System.out.println("hello");
    }
}

Simplifying Comparators

Posted by Patrick Gotthardt in JavaLobby: "(Regarding Closures) Think About Java-Joe!", here. Patrick's example shows how a sort can be simplified by using a closure to replace a Comparator.

Syntax without closures

List<Person> persons = ...;
Collections.sort(persons, new Comparator<Person>() {
   public int compare(Person a, Person b) {
      return a.getAge() - b.getAge();
   }
});

Closures Syntax

List<Person> persons = ...;
Collections.sort(persons) int(Person a, Person b) {
   return a.getAge() - b.getAge();
}

Filtering Lists

From Ray Cromwell, in JavaLobby: "(Regarding Closures) Think About Java-Joe!", here.

Syntax without Closures

findDivisibleBy(List<Integer> l, final int div)
{
  return filter(new Predicate<Integer>()
                {
                       public boolean exec(Integer arg)
                       {
                            return arg % div == 0;
                       }
                });
}

Closures Version (1)

findDivisibleBy(List<Integer> l, int div)
{
   return filter(boolean(Integer x) { x % div == 0 }, l);
}  
findDivisibleBy(Arrays.asList(1,2,5,6,9), 3) => [6,9]

Closures Version (2)

findDivisibleBy(List<Integer> l, int div)
{
   return filter(l) boolean(Integer x) { x % div == 0 };
}  
 
findDivisibleBy(Arrays.asList(1,2,5,6,9), 3) => [6,9]

Various:

TODO: from Ray Cromwell on JavaLobby: "(Regarding Closures) Think About Java-Joe!", this posting.

Modifying Array Contents

Posted by forax in his blog Forax's Blog: Closures and Performance

  static CharSequence[] transform(
    CharSequence(CharSequence) transformation,
    CharSequence... array
   ) {
    for(int i=0;i<array.length;i++) {
      array[i]=transformation(array[i]);
    }
    return array;
  }

applying a transformation

CharSequence(CharSequence) identity = (CharSequence seq) {return seq; };
CharSequence[] seqs=transform(identity,"2","3");
System.out.println(Arrays.toString(seqs));

and overloading parameters

String(Object) bang = (Object o) {return "!"+o; };
CharSequence[] seqs2=transform(bang,"2","3");
System.out.println(Arrays.toString(seqs2));

-- Main.pdoubleya - 22 Aug 2006

Discussion on Syntax

This section is meant to capture discussion. There are several discussion threads already open, see above. You're welcome to add examples of how closures (look like they) would work in Java 7, and comparison with other languages. All I ask is that you avoid purely derogatory comments, or language-related flame wars, or other nonsense. If you don't like Java at all, this is not the page for you. If you think closures are a bad idea because there are better ways to express the same thing, or reasons not to use them, please give examples.

Please sign examples as well with your id, so others can reference them.

As one of the people involved in the debate about Generics, I noticed that when all else failed the proponents of it degenerated into thinly veiled insults. In essence:

"The only reason you don't like them is because you don't understand them".

And by inference

"the reason you don't understand them is because you are not smart enough"

The trend that disturbs me is that while that may have been the last resort in the Generics debate, it appears to have become the first resort in the Closure debate. I hope that this kind of FUD is not indicative of the direction that future extensions to the Java language will take.

In particular it is important to note that it is possible to understand something without agreeing with it.

By analogy: I can understand the concept of an SUV, without agreeing that they are a good thing.

About the example:

Does using CharSequence? in the above example improve its readability? Certainly not for those of us who started on Java before 1.4. (CharSequence? is a new interface which String implements since 1.4)

And is the standard form of the closure in the discussion representing a false economy? We look at:

Object(Object) identity = (Object ob) { return ob; };

And think, gosh, that is much shorter than the three line anonymous inner class! But when the inner class example is putting the braces on their own lines, is it a true comparison?

Shouldn't we advocate it thus:

Object(Object) identity = (Object ob) {
  return ob;
};

Or should we alternatively change the anonymous inner class code to match the formatting of the closure code?

Instead of:

Trans t = new Trans() { 
  Object identity(Object ob) { 
    return ob; 
  }
};

Should we say:

Trans t = new Trans() { Object identity(Object ob) { return ob; } };

And is

CharSequence?(CharSequence?) identity = (CharSequence? seq) { return seq; };

Actually all that more compelling?

It turns out that if we use really long class names and strange formatting we can make any example look bad. If we use object instead of CharSequence? how many keystrokes do we save?

Trans t = new Trans() { Object identity(Object ob) { return ob; } };

vs

Object(Object) identity = (Object ob) { return ob; }

(68 + 8 (shifts for punctuation) keystrokes) vs (52 + 6 keystrokes)

And of course you save the 'enormous' effort of defining the Trans class/interface.

public interface Trans { Object identity(Object ob); }

In the example code does the use of the static keyword indicate that we are supposed to have some kind of 'library' class which just contains closures for other classes to use? That strikes me as a bad programming practice to encourage.

Is it just in there for convenience, or as an oversight, or is there a good reason, will the use of static be an integral part of closures, or is it orthogonal to the example?

--Main.rickcarson - 29 Aug 2006

I think the asynchronous case is quite ready now, it's syntactic sugar for the anonymous inner classes we have today and I personally feel comfortable with the proposed syntax.

The other one, the synchronous, is the new abstraction we don't have yet and it's enormously powerful. The problem I see is the ugly syntax of the method that admits closures as arguments. I would propose a starting point for this syntax that is not so "C function pointer"-based. It would be something like this:

public void foo(int arg1, String arg2, {int} myBlock(int x, double y) throws Exception){
  // ...
}

or

public void foo(int arg1, String arg2, {} myBlock(int x, double y):int throws Exception){
  // ...
}

I'm not totally satisfied with my own proposal, I still see it's a bit ugly, but I think it's clearer with the starting '{}' that the argument is a block of code. I wouldn't use function types in Java if we can avoid it. Remember that this syntax is for the synchronous use case (not the inner class based one), so it has to be remarked at first sight that what we are passing as a parameter is a block of code with parameters (and that it can throw an exception).

You can refine this proposal of syntax, this is only a starting point.

-- Main.xmirog - 05 Sep 2006

To me it seems that the most compelling reason for closures in Java is the ability to re-use try/finally boilerplate. All the other examples seem to be just as nice (or nicer) with inner classes.

So if we instead focus on the problem of re-using try/finally boilerplate, then closures may not be the only answer. There may instead be an answer that has less danger of being abused. Perhaps something annotation-like that allows inserting code around a block (in somewhat an AOP-like fashion, I suppose).

So something like: @WithTransaction(transaction=myTransaction) { //do whatever }

Now we just have to find a nice way to define the code that WithTransaction? will surround the block with.

-- Main.tobega - 05 Sep 2006

-- Can somebody tell us that how the JVM/bytecode should be modified to support the closure? how it works on the new JVM?

As far as I can tell it seems that the closure will become like an anonymous inner class.

But in my annotation-like proposal just above, I think the code should just be injected around the block. Defining the code would be something like this:

@interface (or @class or @aspect?) TimedOperation (?implements @Aspect?){
    Advice around() {
     ///some code
         proceed();//do the block
    //some more code
    }
}

Using it would be:

new interesting sources for search in rapida ( http://www.myfilefind.com and http://www.myrapida.com ) and would like to give the benefit of my experience to you.

@TimedOperation() {
   //your block
}

I think this would be more java-like than the first proposals, because you are somehow using a class-like construct rather than passing functions to functions.

http://fileshunt.com search in -- Main.tobega - 12 Sep 2006

Topic ClosuresSyntaxInJava7 . { Edit | Ref-By | Printable | Diffs r15 < r14 < r13 < r12 < r11 | More }
 XML java.net RSS

Revision r15 - 23 Oct 2008 - 19:52:18 - Main.mike_naton
Parents: WebHome