Protótipo de Closures em Java está "feature-complete"

[quote=Bruno Laturner]Isso é currying de função ou pré-configuração do objeto?

Currying em Java só no dia que tivermos objetos-Função/Bloco[/quote]

Traduzindo, quando Java tiver Closures :slight_smile:

public class X { public X doSomething() { /* statement */ return this; } }

Como posso criar uma closure que retorne ela mesma? Faz sentido?

[quote=peczenyj]public class X { public X doSomething() { /* statement */ return this; } }

Como posso criar uma closure que retorne ela mesma? Faz sentido?
[/quote]

Não tenho a certeza , mas o this dentro do bloco de refere a uma instância da classe X e não ao objeto da closure.

Humm é mesmo, não faria muito sentido!

[size=13][color=blue]Uma resposta interessante para Closures[/color] [/size]

FONTE http://forums.sun.com/thread.jspa?threadID=612915&messageID=3390587

"I would still like to know what the closure abstration really means, then I will be
able to appreciate how well it is supported in a specific language like C++ or Java"

In set algebra, a closure of a set S, w.r.t. a binary operator ‘o’ is a set that contains
all elements of S and itself including the elements ‘a o b’, where a and b belong
to S or the closure of S, i.e. there are no possible elements to be found outside
this closure. e.g. mathematically, the set of all integers is a closure w.r.t. the +
operator. (the sum of two integers still is an integer).

Related to this mathematical notion is the closure of type 3 languages, or
regular expressions if you prefer. If RE is a regular expression, then RE*, i.e.
zero or more catenations of RE, is a closure of RE and is still a regular expression.

In the functional programming language world, a closure is a function where
no free variables can be found. e.g. f(x) <- x+y is not a closure, but g(y) <- f(x)
is one, if y is bound to a value. ‘Currying’ is a closely related concept.

If functions can be a first class citizen in a programming language, i.e. if functions
can be passed as arguments to other functions, just like simple ints etc, closures
are possible in that language no matter how ‘mechanical’ the construct.

In C, closures can be implemented by passed the address of a funcion and a
pointer to some struct that contains values needed by that function. The function
itself can dig those values from somewhere in that struct.

Object oriented language can ‘hide’ that fact a bit more by encapsulating those
values, as well as the function itself in an object. Languages that allow operator
overloading, including the function call ‘operator’ can hide this mechanism even
more by faking the object to be a function.

The possibilities are (almost?) endless here and it’s up to your imagination how
to fake/handle those ‘closures’. BeanShell (an interpreted Java like language) for
example allows this:

Object f() { int x= 42; void g() { System.out.println(&quot;Foo! &quot;+x); } return this; } Object o= f(); o.g();

This code snippet prints “Foo! 42”; function f() acts as a closure for function g() and
can even keep all ‘state’ for that function g().

[quote=Maurício Linhares][quote=Bruno Laturner]Isso é currying de função ou pré-configuração do objeto?

Currying em Java só no dia que tivermos objetos-Função/Bloco[/quote]

Traduzindo, quando Java tiver Closures :)[/quote]

Closure c = { int, int =&gt; int } soma = { int a, int b =&gt; a + b }; Isso, ou algo parecido, é possível?

[quote=Marcio Duran][size=13][color=blue]Uma resposta interessante para Closures[/color] [/size]

(…)
[/quote]
Poste a fonte… http://forums.sun.com/thread.jspa?threadID=612915&messageID=3390587

FONTE

http://forums.sun.com/thread.jspa?threadID=612915&messageID=3390587

Achei que ficou melhor colocado, então postei essa fonte Sun Java Programming

Não há um tipo "Closure". Entretanto, você pode fazer a seguinte declaração:

{int,int =&gt; int} soma = {int a, int b =&gt; a + b };
int x = soma.invoke (2, 3); // deve retornar 5

Não lembro direito (e estou sem o protótipo aqui para testar), mas se não me engano, esses tipos são sempre interfaces, então você pode ter algo como:

class Teste implements {int, int =&gt; int}
{
    public int invoke (int a, int b) { return a + b; }
}

Neal Gafter Discusses Closures, Language Features and Optional Typing
Entrevista com alta resolução e texto simultaneo, InfoQ: Mais detalhes de Closures e JVM 1.7

:idea: http://www.infoq.com/interviews/gafter-closures-language-features-optional-typing

citando alguém mais pra cima nesse post, rola um Too much Gambiarra aí ou um Warning: Not Syntax Sugar? :smiley:

Java desempenha um papel legal de compilador para novas linguagens sob a plataforma / linguagens dinâmicas (claro que nem sempre da maneira ideal para as linguagens dinâmicas). Agora essa incorporação de comportamento não previsto anteriormente no projeto da linguagem java tá de matar. =D

T+

[quote=thingol]Uma coisa que seria interessante em closures é se eu pudesse fazer currying também.

Não cheguei a brincar suficientemente com o protótipo final (e olhe que eu estou acompanhando isso desde as primeiras propostas do Gafter), mas eu gostaria de fazer algo semelhante ao que posso fazer no Boost:

#include &lt;boost/asio.hpp&gt;
...

boost::asio::async_read (socket, boost::asio::buffer (buf, 0, nbytes), 
    boost::bind (&MyClass::MyReadHandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

onde “boost::bind” é um template que efetua o currying de MyReadHandler, passando a “this” o ponteiro para função-membro “MyClass::MyReadHandler”, e então passando os parâmetros a essa função-membro: error e bytes_transferred.

[/quote]

Isso daí que o thingol quer fazer tá parecendo com essa discussão aqui

T+

[quote=thingol][quote]
Closure c = { int, int => int } soma = { int a, int b => a + b };
[/quote]

Não há um tipo "Closure". Entretanto, você pode fazer a seguinte declaração:

{int,int =&gt; int} soma = {int a, int b =&gt; a + b };
int x = soma.invoke (2, 3); // deve retornar 5

Não lembro direito (e estou sem o protótipo aqui para testar), mas se não me engano, esses tipos são sempre interfaces, então você pode ter algo como:

class Teste implements {int, int =&gt; int}
{
    public int invoke (int a, int b) { return a + b; }
}

[/quote]

Sim, surgirá uma quantidade infinita de interfaces dentro do pacote javax.lang.function correspondentes aos closures. Uma bela gambiarra no compilador!

Admitindo que isso é possível ( o que me parece que não seja, mas tb não testei) estaria no mesmo nivel de codigos como

O objetido de um tipo de função (Function Type) é conter codigo, aka é o corpo entre chaves em um objeto ( já que e´a única coisa em java que não é uma objeto … além dos primitivos, mas esse já têm o auto-boxing)
Tipo de função são apenas um boxing de codigo. Desde ponto de vista não ha razão para tentar escrever o código acima (até porque é “boxing” duplo ) e acredito que seria um anti-pattern pelo simples motivo que não é logico

De outro ponto de vista tipos de função ( de que as closures são um sub-tipo) não são interfaces, são objetos. São objetos que implementam certas interfaces. Mas tanto as interfaces como os objetos são criadas em runtime , logo, elas nem existem em tempo de compilação o que levaria esse código a não compilar. ( como disse não testei, mas se funcionar não faz sentido algum…)

invoke em que ser chamado explicitamente?

Acho sacanagem ter que fazer soma.invoke(2,3) em vez de soma(2,3). Se closures são funções, ajam como tal.

Ainda acho mais claro usar “soma.invoke (2, 3)” que “(*soma) (2, 3)” - que é o caso do C quando usamos ponteiros de função. (Em C++ pode-se usar (*soma) (2, 3) ou soma (2, 3) mas C++ tem 200 jeitos de fazer a mesma coisa, e um menos intuitivo que o outro).

Mas realmente é uma gambiarra que existe porque a alternativa mais intuitiva (usar “soma (2, 3)”), segundo o sr. Neal Gafter, tem alguns problemas de ambigüidade sintática que são difíceis de resolver.

[quote=Bruno Laturner]invoke em que ser chamado explicitamente?

Acho sacanagem ter que fazer soma.invoke(2,3) em vez de soma(2,3). Se closures são funções, ajam como tal.[/quote]

A meu ver ai é que tá a sacada… closures são objetos. “funções puras” continuam não existindo.

Imagine que vc passa uma função com parametro de um método tipo assim


<T> void doSomething(List<T> list, { T=> void} function ) {

    for (T t : list){
         function.invoke(t);
   }
}

Se vc não tiver o invoke, como executaria a função em cima de cada t ?
Algo como function(t) implicaria que function é um método da classe, o que não é verdade.

[quote=sergiotaborda]Se vc não tiver o invoke, como executaria a função em cima de cada t ?
Algo como function(t) implicaria que function é um método da classe, o que não é verdade.[/quote]
Respondendo ambos ao mesmo tempo:

Resolvemos da mesma forma que fazemos com atributos do objeto e variáveis locais, ambos com o mesmo identificador, usando escopo.

Edit: A questão não é “não ter invoke”, é ele não ser a única opção.

[quote=Bruno Laturner]
Respondendo ambos ao mesmo tempo:

Resolvemos da mesma forma que fazemos com atributos do objeto e variáveis locais, ambos com o mesmo identificador, usando escopo.

Edit: A questão não é “não ter invoke”, é ele não ser a única opção.[/quote]

Tudo bem que não seja a única opção. Mas existem opções melhores que outras…
Não entendi como o escopo poderia ajudar no exemplo que dei. Explique melhor essa ideia.

[quote=peczenyj]public class X { public X doSomething() { /* statement */ return this; } }

Como posso criar uma closure que retorne ela mesma? Faz sentido?
[/quote]

Usa o Y Combinator.

function() não seria o método da classe, seria a função mais próxima definida no escopo.

É um problema para visualizar isso na hora da manutenção? Bem, sim.