12 novembro 2007

Java 7 with Chained Invocation

This weekend Claudio Miranda, a friend and co-worker of mine from Brasília, came to São Paulo to assist give a presentation about "Tools and Tips to Solve Performance Issues in Java Applications" (yes, this is his presentation name) at Conexão Java. After some beers and talks about Java, I introduced him an idea I have been thinking about for a few days.

In Ruby, the return statement is implicit. In Java, we always have to declare which return type the method has. But what's happening is that this kind of method declaration is becoming common these days:
class Foo {
public Foo doSomething() {
...
return this;
}
...
}

This gives us a shortcut to do some chained invocations, for example:
Foo foo = new Foo().doSomething().doAnotherThing();

To give developers a better shortcut, my idea is to let them code methods with return type declared as "this":
    public this doSomething() {
...
}

After I showed Claudio my idea, he told me somebody already thought something like that, and there's a lot more suggestions than just this one. So don't think this is a worthless improvement. Somebody else thinks the same as I do :D

The difference between my suggestion and the one from Matthias Ernst, is that void would continue to be void. No return. The use of this, which has the concept of the current object,
would be convenience and not something magic, as declaring void and expect that to return the object itself. Another great interesting point to look is the integration with Covariant Types.

Let's take the Bar example:
class Bar extends Foo {}

// with current JSL and explicit return this; this would not compile
Bar bar = new Bar().doSomething();

// to fix, you must explicitly cast the returning object
Bar bar = (Bar) new Bar().doSomething();

Mixing implicit return this and covariant types, no cast is needed and we would have chained invocations easily! Besides, this is a small change into Java Compiler. The generated bytecode should be compatible with Java 1.3. Comments?

6 comentários:

Vitor Fernando Pamplona disse...

Alarm! Alarm!

Sinto uma perda de foco! :)

A mudança continua te exigindo digitar o retorno. Digitar "public this" ou "return this" dá no mesmo. Isso não muda nada no "Easy Development". Em outras palavras, é firula :)

[]s

marcospereira disse...

Concordo com o Vitor, Java não precisa de mais mudanças. O que precisamos mesmo é de evolução na plataforma para suportar bem as linguagens dinâmicas que surgiram nos últimos anos.

Bruno, dá para emular o que vc fez com tipos covariantes usando generics:

public class Foo[T extends Foo] {

public T doSomething() {
System.out.println("I do something");
return (T)this;
}

public static void main(String[] args) {
Bar bar = new Bar().doSomething().anotherThing();
}
}

class Bar extends Foo[Bar] {
public Bar anotherThing() {
System.out.println("I do another thing");
return this;
}
}

Usei "[" porque o blogger reclamou. De qualquer modo fica a pergunta: duck typing não é mais interessante?

valeuz...

Tetsuo disse...

Eu já usei essa solução com generics uma vez, funcionou muito bem.

'De qualquer modo', acho que duck typing não tem muito a ver com esse caso...

marcospereira disse...

Ronald, sobre duck typing:

class Foo {
def doSomething() {
println "foo"
return this
}

static main(args) {
Bar bar = new Bar().doSomething().anotherThing();
}
}

class Bar extends Foo {
def anotherThing() {
println "bar"
return this
}
}

O tipo deixa de importar desde que os dispatchs sejam satisfeitos. Era disso que eu falava.

valeuz...

Tiago "PacMan" Peczenyj disse...

syntax sugar! :)

poderia ser assim:

public @this myMethod(){
...
}

Anônimo disse...

escreve em português caralho!

Contato

Email:bruno.borges(at)gmail.com

LinkedIn: www.linkedin.com/in/brunocborges
Twitter: www.twitter.com/brunoborges
Comprei e Não Vou
Rio de Janeiro, RJ Brasil
Oracle
São Paulo, SP Brasil