Proposta de closures para Java

47 respostas
fcmartins

No blog do Peter Ahé, foi postado o link p/ essa proposta para a inclusão de closures no Java:
Closures for Java.

É uma leitura interessante, o documento ainda está em uma versão inicial, aberta a modificações.

O documento é assinado pelo próprio e pelo James Gosling, entre outros.

47 Respostas

T

Um exemplo bobo, que não faz jus às capacidades de “closures”.

import java.util.*;

class Cliente {
    private String nome; 
    private int id;
    public String getNome() ... bla bla bla ...
}

class TesteClosures {
    public static void main(String[] args) {
        List<Cliente> clientes = new ArrayList<Cliente>();
        
        //-- Ordenando com "closures"
        int(Cliente,Cliente) ordemCrescente = (Cliente c1, Cliente c2) {
            int ret = c1.getNome().compareTo(c2.getNome());
            if (ret != 0) return ret;
            return c1.getId() - c2.getId();
        });
        int(Cliente,Cliente) ordemDecrescente = (Cliente c1, Cliente c2) {
            return -ordemCrescente(c1, c2);
        }
        // ordem crescente
        clientes.sort (ordemCrescente);
        // ordem decrescente
        clientes.sort (ordemDecrescente);
        
        //-- Usando um comparator tradicional e inner classes
        // ordem crescente
        clientes.sort (new Comparator<Cliente>() {
            public int compare(Cliente c1, Cliente c2) {
                int ret = c1.getNome().compareTo(c2.getNome());
                if (ret != 0) return ret;
                return c1.getId() - c2.getId();
            }
        }
        // ordem decrescente
        clientes.sort (new Comparator<Cliente>() {
            public int compare(Cliente c1, Cliente c2) {
                int ret = c1.getNome().compareTo(c2.getNome());
                if (ret != 0) return - ret;
                return c2.getId() - c1.getId();
            }
        }
    }
}
T

Acho que este é um exemplo melhor.

import java.sql.*;

class TesteClosures2 {
    /**
     * Isto serve para delimitar um escopo onde um conjunto de comandos
     * deve ser obrigatoriamente terminado com o fechamento de um
     * arquivo, Connection, Recordset e outras coisas que implementam
     * Closeable.
     * Inspirado no constructo "using" do C#
     */
    public static void using(Closeable clos, void() commands) {
        try {
            commands();
        } finally {
            try { clos.close(); } catch (IOException ex) {ex.printStackTrace();}
        }
    }
    
    public static void main(String[] args) {
        Connection conn = ...;
        using (conn) {
            RecordSet rset = ...;
            using (rset) {
                rset.next();
            }
        }
    }
}

EDIT - melhorei um pouco a implementação de “using”. Agora está com a mesma semântica do C#.

Daniel_Quirino_Olive

Uma idéia seria simular high-order functions com closures:

public static void foo(Closure c, Object[] array) {
       for(Object o : array) {
              c(o);
       }
}
//...
Closure c = (Object param) { System.out.println("Param = "+param);};
MyClass.foo(c, algumArrayQualquer);
Daniel_Quirino_Olive
Daniel Quirino Oliveira:
Uma idéia seria simular high-order functions com closures:
public static void foo(Closure c, Object[] array) {
       for(Object o : array) {
              c(o);
       }
}
//...
Closure c = (Object param) { System.out.println("Param = "+param);};
MyClass.foo(c, algumArrayQualquer);

Nossa, só agora que eu li o paper e vi que já existe até uma proposta para a sintaxe das closures. Ignorem o meu exemplo na medida do possível :D

louds

Muito interessante, tou lendo o paper.

louds

Coloca suporte a open types/ mixins e Java volta ao leading edge das linguagens.

Paulo_Silveira

qual é o problema de classes anonimas? escrever meia linha a mais?

ok, vai facilitar, mas nao vejo essas coisas como extremamente necessarias, diferente de generics e enums.

java ja nao vai mais poder ser chamado de “simples”. porque vao existir 35 jeitos diferentes de fazer a mesma coisa.

wmitsuda

Paulo Silveira:
java ja nao vai mais poder ser chamado de “simples”. porque vao existir 35 jeitos diferentes de fazer a mesma coisa.

Perl?

louds

Sim, classes anônimas são tão escrotas de usar p/ qualquer idioma de programação funcional que ninguém usa.

Pensa no seguinte:

class ArrayList<T> {
  int reduce(int init,(int) c(int, T)) {
     int r = init;
     for(Object O : this.array) r = c(r, O);
     return r;
  }
}

ArrayList<String> r = new ArrayList<String>();

r.reduce(0, (int) (int c, String o) { return c + o.length(); });
fcmartins

Você poderia deixar um comentário no blog dele, acho que ele postou justamente p/ ter feedback dos usuários. Como só tenho um conhecimento superficial do assunto não vou me atrever a comentar, mas acho importante dar esse tipo de sugestão.

urubatan

clusures são legais …
eu usava bastante method pointers em delphi :smiley:

sei que não é a mesma coisa …
mas a sintaxe é mais simples que classes anonimas …

mas concordo com o paulo, não vejo como algo necessário …

T

Qual é a diferença de “function types” e “delegates”? O James Gosling vai ter de engolir as próprias palavras :stuck_out_tongue: - já que ele assinou a proposta do “Closures for Java.”

http://java.sun.com/docs/white/delegates.html

http://msdn.microsoft.com/vjsharp/productinfo/visualj/visualj6/technical/articles/general/truth/default.aspx

De qualquer maneira, é uma adição bem-vinda.

Outra coisa legal é que dessa maneira iremos ter algo que é muito semelhante ao Pascal, que são “nested functions”.

S
Daniel Quirino Oliveira:
Uma idéia seria simular high-order functions com closures:
public static void foo(Closure c, Object[] array) {
       for(Object o : array) {
              c(o);
       }
}
//...
Closure c = (Object param) { System.out.println("Param = "+param);};
MyClass.foo(c, algumArrayQualquer);
O que isso faz? Você tá passando um método (ou função, tanto faz) como parâmetro pra outro método e aplicando ele no array? É uma flexibilidade, mas não é bastante confuso? Qual a vantagem real disso?
Daniel_Quirino_Olive
Schuenemann:
Daniel Quirino Oliveira:
Uma idéia seria simular high-order functions com closures:
public static void foo(Closure c, Object[] array) {
       for(Object o : array) {
              c(o);
       }
}
//...
Closure c = (Object param) { System.out.println("Param = "+param);};
MyClass.foo(c, algumArrayQualquer);
O que isso faz? Você tá passando um método (ou função, tanto faz) como parâmetro pra outro método e aplicando ele no array? É uma flexibilidade, mas não é bastante confuso? Qual a vantagem real disso?

http://www.joelonsoftware.com/items/2006/08/01.html

S

Eu já tinha lido isso, mas sinceramente não entendi.
A impressão que tive é que isso é só um jeito de se escrever código com menos linhas, porém bem mais confuso. E fica ainda pior quando ele declara a função “on the fly”.

E ainda diz no final:

Sendo que o exemplo na explicação foi uma concatenação?

Não consegui entender a utilidade disso.

Thiagosc

Não entendi a relação entre delegates e closures. Por que ele teria que engolir as próprias palavras?

Pelo que lembro de quando estudei C# logo que saiu, a sintaxe de delegates era meia confusa e eles usam operadores sobrecarregados (eca!!) para trabalhar com delegates, tipo ‘+’ para adicionar e ‘-’ para remover. Sou da opinião que operadores deveriam ser usados apenas com números.

Achei totalmente tosco, pois não acrescentava nada ao que é feito com Listeners em Java e apenas complica um pouco mais a sintaxe.

louds

Minha sugestão é que brinquem um pouco com linguagens funcionais, elas resolvem uma enorme gama de problemas de forma muito mais clara e simples que OO. Ter suporte a closures permite uma porrada de coisas.

Pelo que eu vi, não vai ser possivel implementar binding e currying, mas já é um enorme avanço.

Os exemplos de gerenciamento de recursos são um bom exemplo de idiomas legais. Com static imports fica ainda mais legais.

import static closures.Support;

....
Connection con = ...
withResource(con) {
   con.createBlaBlaBla
   ....
}

Imagine fazer isso com classes anônimas? Ou na mão com try / finally.

Outros usos legais são para criar geradores de forma mais simples.

T

E como mostrei no meu segundo post, é trivialmente simples escrever um método desses de gerenciamento de recursos. Implementar a palavra-chave “using” do C# em Java com um método de poucas linhas, e exatamente com a mesma sintaxe, é muito legal.

dudaskank

uma dúvida…

closures = ponteiro de função?

outra coisa, isso aí de using fica muito estranho, isso tem relação com o closure? pra mim parece igual ao with() de várias linguagens… algo assim:

with(System.out) { println("To com preguiça"); println("De digitar"); println("System.out"); }

flw

danieldestro

Daqui a pouco código Java vai ficar ilegível.

T

a) Dei o exemplo do “using” que é uma forma estruturada de efetuar gerenciamento de recursos. Se você tem de usar coisas que têm de ser obrigatoriamente fechadas (como conexões e arquivos) e odeia ter de ficar escrevendo um monte de “try/catch/finally” vai ver que esse “using” é uma mão na roda.

Não é a mesma coisa do “with” que existe em Pascal (onde nasceu), em JavaScript e em VB (argh).

b) Closures podem ser usadas para muitas outras coisas; como foi dito, podemos usar uma versão limitada de programação funcional. Lembro de um post em que alguém solicitava como efetuar o quadrado de uma função. Lido literalmente, o post solicitava composição de funções.

h = g o f

onde “o” é o operador de composição de funções.

é a mesma coisa que:

defina uma função h(x) que retorna g(f(x)).

Digamos que quiséssemos definir uma função que recebesse uma outra função e retornasse sempre o quadrado do valor retornado por essa função. Por exemplo, dado que existe a função Math.log, queremos que essa função retornasse Math.log(x) * Math.log(x).

public static double(double) quadrado (double(double) f) {
    return new double(double x) : f(x) * f(x);
}
...
public static void main(String[] args) {
    // Teste para log
    double(double) logquadrado = quadrado (Math.log);
    double x = logquadrado (20);
    double y = logquadrado (Math.PI);
}
keller

IMHO, Que codigo feio!
Muito complexo, sinceramente não gostei.

T

Este é um exemplo de um código que poderia se beneficiar de algum recurso de aliasing. Ele já faz falta com Generics; mais falta ainda irá fazer com closures.
Ele poderia ser resolvido mais ou menos como:

T

Quiá, quiá, quiá, com Generics já é ilegível, por que é que só com Closures vai ficar ilegível?

public static <T extends Object & Comparable>&lt? super T&gt&gt T max(Collection&lt? extends T&gt coll)

Closures têm um uso especializado. Alguns são fáceis de usar, como os tais “function types” que evitam o uso esquisito de classes anônimas. Outros (como a tal composição de funções que estou tentando mostrar) talvez sejam mais difíceis de usar, e relegados a bibliotecas prontas (em C++ normalmente você usa os templates da STL; é muito difícil alguém escrever templates tão complicados quanto os da STL.)

Thiagosc

Putz. Esse Java 6 devia sair logo, assim o 7 deslanchava! :slight_smile:

Gostando ou não gostando, ficar parado é pedir para morrer. Eles só precisam não avacalhar de vez e adicionar um mundo de coisas assim como estão fazendo com o C#, aí sim seria um horror.

Por exemplo, aquela nova feature do C# de dividir a classe em vários arquivos é uma porcaria. Francamente, se a sua classe é grande demais para caber num arquivo só será que não há nada errado na sua estrutura de classes?

A importância dessa feature talvez não seja a “revolução” que irá causar, porque acredito que a maioria dos desenvolvedores que usam Java só querem fazer o trabalho e não estão muito lá interessados em explorar esse tipo de coisa, mas sim em manter o Java “novo” e continuar atraindo novos desenvolvedores.

Obs.: eu sou a favor dessa nova feature porque possibilitará muitas coisas interessantes.

danieldestro

Foi o que eu disse. A cada dia ela fica mais ilegível.

Thiagosc

O que há de ilegível nisso? É preferível ter uma declaração dessa explícita do que escondida em algum lugar ou implícita.

As pessoas deveriam parar de pensar simplesmente em economizar digitação às custas da legibilidade.

T

Isso foi feito para evitar aquele famoso quebra-galho que existe no NetBeans e em versões anteriores do C# - ter de cercar o código gerado pela IDE com um comentário especial, ou um constructo especial da linguagem no caso do C#.
Em vez disso, esse código gerado fica em um arquivo separado, para você não ficar mexendo ou fuçando nele.

T

Thiagosc:
thingol:

Quiá, quiá, quiá, com Generics já é ilegível, por que é que só com Closures vai ficar ilegível?

public static <T extends Object & Comparable>&lt? super T&gt&gt T max(Collection&lt? extends T&gt coll)

O que há de ilegível nisso? É preferível ter uma declaração dessa explícita do que escondida em algum lugar ou implícita.

As pessoas deveriam parar de pensar simplesmente em economizar digitação às custas da legibilidade.

Mas o problema não é o de economizar digitação. São os conceitos que cada vez ficam mais complicados. Se você leu o tal do Tutorial de Generics do Gilad Bracha, em que ele mostra exatamente esse exemplo, vai ver que realmente dá um “nó na cabeça”.

Guilherme_Silveira

Eu só fico triste que pra matemática ainda o java fica muito, mas muito, atrás do octave.

ps: por mais cheio de bugs e problemas do octave

louds

Guilherme Silveira:
Eu só fico triste que pra matemática ainda o java fica muito, mas muito, atrás do octave.

ps: por mais cheio de bugs e problemas do octave

Guilherme, provavelmente você deveria estar olhando para o Fortress e não para Java. Tudo bem que o Fortress ainda é um projeto de pesquisa.

Guilherme_Silveira

Entao Louds, eu preciso escrever um metodo (descida maxima, por exemplo), em tres linhas… o octave faz isso em tres, sendo duas para declarar os metodos… essa que eh a facilidade que um matematico precisa…

O pessoal de computacao costuma achar que o matematico deveria aprender mais programacao, mas nao acontece na pratica… nem o pessoal de analise numerica programa tanto assim

Eu tinha lido do fortress qdo saiu, mas de la pra ca nunca vi alguem usar.

Eles tentam simular a notacao matematica que ja ajuda… mas… ao mesmo tempo, outras linguagens, como o R, tem milhoes de pacotes de estatistica, eqto o Java nao tem (e o Fortress? nos docs la nao vejo nada…).

A

Além desses casos de acesso a recursos e manipulação de coleções, closures permitem estilos de programação que não seriam práticos de outra forma. Dois exemplos que me ocorrem são o Rake (descrito pelo Fowler aqui) em Ruby e quase todos os programinhas dentro desse tutorial de Scala.

Uma questão interessante é o quanto a introdução dessa feature no Java agora fará diferença. Java já é uma linguagem velhinha e uma proporção muito grande do trabalho com ela é lidando com bases legadas. Mesmo em projetos novos, muito código é dedicado a interagir com APIs e frameworks pré-existentes. Usar closures nesse tipo de ambiente pode levar a frankensteins. Por outro lado, o potencial ganho de produtividade e expressividade é bem grande. Se tivessem feito isso uns 8 anos atrás seria tudo mais fácil… (o Guy Steele disse que sugeriu colocar closures de verdade naquela época, mas o pessoal não quis por medo de alocação implícita de objetos no heap…)

A

Uma coisa que eu não entendo é por que ainda não soltaram nenhum código (nem binário) do Fortress. Primeiro que o Steele deu uma palestra famosa sobre “Growing a Language” defendendo linguagens extensíveis com um modelo semelhante aos projetos de código aberto… Segundo que a Sun vive propagandeando que adotou open source como fundamento para sua estratégia na área de software… (Acho que agora eu deveria citar aquele ditado besta sobre teoria e prática…)

Mauricio_Linhares

thingol:
Mas o problema não é o de economizar digitação. São os conceitos que cada vez ficam mais complicados. Se você leu o tal do Tutorial de Generics do Gilad Bracha, em que ele mostra exatamente esse exemplo, vai ver que realmente dá um “nó na cabeça”.

Toda aquela parte de wildcards dá um “nó na cabeça”.

? (unknown) é um tipo desconhecido, mas nós sabemos que qualquer tipo em Java tem que ser no mínimo Object (já que os tipos primitivos não podem ser utilizados em genéricos), então porque em vez de se utilizar “?” não se assume simplesmente que é object (que é o que o compilador termina fazendo de qualquer modo quando não existem limites inferiores ou superiores)?

A sintaxe dos genéricos me ajudou a “limpar” e deixar um bocado de código mais legível, mas algumas coisas na implementação ainda não “caíram” por aqui não.

Coisa bizarra que um dos alunos de um curso que eu dei descobriu:

import org.junit.Test;

public class TestPrint {

	@Test
	public void testErroGenerico() {
		
		int[] ints = {1,2,3,4,5};
		
		TestPrint.printArray(ints);
		
	}

	@Test
	public void testCertoGenerico() {
		
		Integer[] ints = {1,2,3,4,5};
		
		TestPrint.printArray(ints);
		
	}
	
	public static <T> void printArray(T... objects ) {
		
		System.out.printf("Array: %s Class: %s%n%n", objects, objects.getClass());
		
		for (T object : objects) {
			System.out.printf("Objeto: %s%n", object);
		}
		
		System.out.println();
		
	}
	
}

Executando esse teste do JUnit a saída é a seguinte:

Array: [[I@85af80 Class: class [[I

Objeto: [I@c51355

Array: [Ljava.lang.Integer;@15fea60 Class: class [Ljava.lang.Integer;

Objeto: 1
Objeto: 2
Objeto: 3
Objeto: 4
Objeto: 5

Na execução do primeiro método, onde ele tem que fazer o autoboxing com vararg genérico ele “cria uma classe” do tipo “I” e coloca em uma referência a um array de array de “I” (por isso que imprime “[[” antes do “I”).

Já na segunda chamada, onde ele não precisa mais fazer autoboxing, as cosas funcionam normalmente.

Talvez seja também por que quando você passa um array direto pro vararg o compilador acha que já é o “array do vararg” e termina se perdendo, aí juntou com autoboxing e genéricos e pronto, lascou tudo :smiley:

É claro que é uma besteira, mas alguém pode terminar caindo nesse bug aí e ficar sem saber o que está acontecendo. Acho que já tá bom de ficar “apertando e puxando” o pobre do Javac e o bytecode da JVM.

Luca

Olá

Making Java an obscure language By Eugene Kuleshov on Java

[]s
Luca

bzanchet

Sou contra. Batendo na tecla de sempre (“por que deixar a linguagem java maior e mais complexa?”), pergunto: não é uma idéia melhor deixar esses comandos de “alta expressividade” apenas em uma linguagem de script, dinâmica e moderna, e fazer esta linguagem inter-operável em relação às bibliotecas e código Java já existente? (ahnn… groovy :mrgreen: )

louds

Guilherme Silveira:
Entao Louds, eu preciso escrever um metodo (descida maxima, por exemplo), em tres linhas… o octave faz isso em tres, sendo duas para declarar os metodos… essa que eh a facilidade que um matematico precisa…

O pessoal de computacao costuma achar que o matematico deveria aprender mais programacao, mas nao acontece na pratica… nem o pessoal de analise numerica programa tanto assim

Eu tinha lido do fortress qdo saiu, mas de la pra ca nunca vi alguem usar.

Eles tentam simular a notacao matematica que ja ajuda… mas… ao mesmo tempo, outras linguagens, como o R, tem milhoes de pacotes de estatistica, eqto o Java nao tem (e o Fortress? nos docs la nao vejo nada…).

Até onde eu vi, o Fortress continua na fase de pesquisa, se tem alguma coisa funcionando, deve ser um protótipo e ninguém viu.

Fora isso, Java foi feito para tudo menos uma linguagem para matemáticos, então eles não deveriam mesmo estar usando-a. Simples assim.

Luca

Olá

Concordo que Java não foi feito para matemática até porque antigamente a representação de ponto flutuante era inadequada (para não dizer coisa pior). Mas isto já mudou.

Hoje em dia há muita gente aproveitando as facilidades do Java para escrever código com menos vazamento de memória. Processamento científico geralmente é CPU-bound e com uso intenso de memória. Os ponteiros do C propiciam vazamentos e dificultam a depuração de erros de programas que usam muita memória.

Pelo exposto acima, muitas bibliotecas famosas escritas em Fortran ou C já foram convertidas para Java e quase todas com performance bastante aceitável. Uma das boas fontes para aqueles que são do ramo é o site:
http://math.nist.gov/javanumerics/

[]s
Luca

Thiagosc

thingol:
Isso foi feito para evitar aquele famoso quebra-galho que existe no NetBeans e em versões anteriores do C# - ter de cercar o código gerado pela IDE com um comentário especial, ou um constructo especial da linguagem no caso do C#.
Em vez disso, esse código gerado fica em um arquivo separado, para você não ficar mexendo ou fuçando nele.

Bom, não foi isso o que eu li, eu li um artigo sobre o C# 3 e isso é mostrado como uma “feature” para o desenvolvedor e não para IDEs. Mas considerando que seja isso mesmo, por um acaso é bom???

Se fosse no Java já teria meia dúzia de usuários daqui chorando as pitangas de que isso era “horrível, horroroso, horrendo”, que o “Java está morto”, que o fim dos tempos chegou, que a linguagem script faz tudo 1000 vezes melhor, etc, etc, etc…

Mauricio_Linhares

Eu, pessoalmente, prefiro que eles refaçam a linguagem do 0, com compatibilidade 0, pra resolver essas coisas, não precisa nems ser Java, basta dar um apoio maior a essas linguagens mais “mainstream” que estão surgindo pra JVM, como Groovy e JRuby.

Outra coisa muito importante seria também fazer uma reengenharia no bytecode e no modo que a JVM em si trabalha, como a adição do “invoke dynamic”, que seria ótimo pra todas essas linguagens de tipagem dinâmica, além do conceito de open classes, que poderia acabar com as macumbas que tem que ser feitas com CGLIB e ASM hoje pra se instrumentar classes.

Kenobi

Eu, pessoalmente, prefiro que eles refaçam a linguagem do 0, com compatibilidade 0, pra resolver essas coisas, não precisa nems ser Java, basta dar um apoio maior a essas linguagens mais “mainstream” que estão surgindo pra JVM, como Groovy e JRuby.

Outra coisa muito importante seria também fazer uma reengenharia no bytecode e no modo que a JVM em si trabalha, como a adição do “invoke dynamic”, que seria ótimo pra todas essas linguagens de tipagem dinâmica, além do conceito de open classes, que poderia acabar com as macumbas que tem que ser feitas com CGLIB e ASM hoje pra se instrumentar classes.

E o que você faz com o legado de aplicações que existe hoje em dia ? Vira pro seu cliente e fala : - Reescreva tudo ?

Sinceramente, um dos pontos de decisão de muitos IT Managers, foi a compatibilidade retroativa da plataforma.

São muitas as questões que envolvem a escolha de uma plataforma e preservar seu investimento ao longo dos anos, faz parte de muitas estratégias de ROI, quando justificam a construção de algum sistema.

Vejo isso no dia-a-dia no banco, onde a plataforma homologada pela frança é 1.3.1 (Trabalhamos com a 1.4.2_+mais recente) , mas isso é comum nesse tipo de empresa.

Acredito que a plataforma deva evoluir, mas não dá para ignorar o legado de bilhões de dólares investidos.

louds

Kenobi, nada impede de se criar uma versão que seja backward-compatible, mas não forward-compatible. Isso é perfeitamente possivel, e de uma forma mais branda, já acontece.

O que poderia ser feito é criar uma nova versão que suporta apenas o bytecode antigo e a linguagem é completamente diferente.

Kenobi

louds:
Kenobi, nada impede de se criar uma versão que seja backward-compatible, mas não forward-compatible. Isso é perfeitamente possivel, e de uma forma mais branda, já acontece.

O que poderia ser feito é criar uma nova versão que suporta apenas o bytecode antigo e a linguagem é completamente diferente.

Mesmo assim, muitas companhias não poderiam migrar, pois é sabido que a cada número X de linhas de código, você tem um número Y de bugs.

Esses dados são inerentes à cada companhia, equipe etc… Entretanto, você vai necessitar em algum ponto ou melhorar seu código, ou estender a funcionalidade.

Nessa hora, você não terá a compatibilidade, ou terá que escrever usando a linguagem antiga, sem se beneficiar das novas implementações.

Java está se movendo, mas a questão é delicada. De um lado você tem os entusiastas, early adopters pressionando por melhorias. Do outro, você tem um legado, uma indústria constituída poderosa, por onde passa bilhões de dólares em investimento.

Quando se torna um gigante, seu passo tende a ser mais lento. Por isso muitas companhias quebram sua estrutura organizacional em companhias menores.

Talvez o Java possa fazer o mesmo, investindo numa linguagem dinâmica, que possa fazer uso da JVM e estar completamente atualizada às tendências de programação.

Enquanto o Java, evolui num rítmo mais lento, devido ao peso de suportar muito investimento em tempo, recursos, esforço etc e tal .

T

Se houvesse closures, talvez o sr. David Hall conseguisse escrever a sua biblioteca de algoritmos genéricos de forma mais simples.

http://jga.sourceforge.net/index.shtml

T

O Neal Gafter (Google) atualizou a sintaxe de closures.
Ele está estudando isso, juntamente com o Gilad Bracha e o Peter von der Ahé (Sun). O James Gosling aparece também na proposta, mas não sei se ele “apita muito” nessa questão.

Postem no blog do Neal se tiverem alguma sugestão.

T

Agora o Gafter arranjou um web site só para isto (javac.info).

Vejam a nova proposta (versão 0.3):

http://www.javac.info/closures-v03.html

Criado 18 de agosto de 2006
Ultima resposta 24 de out. de 2006
Respostas 47
Participantes 18