Closures vs Delegates

Olá!

Pessoal, alguém poderia me explanar algo sobre a diferença do conceito de Closures pros Delegates (.NET, Javascript)?

Abraços

Bom, pra mim Closures é a capacidade de se declarar funções dentro de outras, enquanto Delegates são mais parecidos com os ponteiros de funções do C.

O que acontece é que apesar de funcionar de formas diferentes, ambos servem para quando você quer passar uma função como argumento para outra. Então, nesse caso, acabam sendo utilizados da mesma forma.

Acho que é isso.

Uma closure captura o contexto onde foi usada.
Um delegate normalmente é um método declarado no mesmo nível dos outros métodos e somente captura o objeto referente à classe onde foi declarado.
Por exemplo, digamos que houvesse closures em Java.

Você poderia usar algo como:

boolean ascending = true; // note que isto não precisa ser uma variável final, como seria requerido em Java normal
Collections.sort (col, { C x, C y => ascending ? x.getField().compareTo (y.getField())});

Mas se houvesse delegates em Java, você não poderia usar o valor de ascending. Você teria algo como:

public boolean compare (C x, C y) { return x.getField().compareTo (y.getField()); }
...
Collections.sort (col, delegate compare);

onde você passa só o nome do método, não um objeto contendo o tal método.

Está quaaaaaaaase claro após essas explicações, só preciso refletir mais um pouco ahueuaehaeu.

Valeu!

Então pelo que percebi, uma closure tem livre acesso ao escopo em que está inserida, certo? Diferente de classes anônimas… o mesmo exemplo com classes anônimas:

final boolean ascending = true;

Collections.sort(col, new Sorteable(){
    public boolean compare(C x, C y) {
        return ascending ? x.getField().compareTo(y.getField());
    }
});

Não tenho certeza se o compare de Sorteable anonimo consegue mesmo acessar o ascending la em cima. Se consegue, porque tem que ser final? (Essa é outra das minhas dúvidas de sempre que nunca lembrava de perguntar aheuhaeuh).

[quote=Link_pg]
Não tenho certeza se o compare de Sorteable anonimo consegue mesmo acessar o ascending la em cima. Se consegue, porque tem que ser final? (Essa é outra das minhas dúvidas de sempre que nunca lembrava de perguntar aheuhaeuh).[/quote]

Consegue, mas só se for final. Agora, sobre o por quê, senta que lá vem história:

http://mindprod.com/jgloss/anonymousclasses.html


http://bugs.sun.com/view_bug.do?bug_id=4351453

É isso aí. Para que uma função seja uma closure, são necessários três requisitos:

  1. A função deve ser um objeto de primeira classe. Isso significa dizer que ela pode ser manipulada sem restrições, em comparação com outras estruturas da própria linguagem. Em Java, você pode passar objetos como parâmetro para métodos, e objetos também podem ser retornados por métodos. Mas o mesmo não pode ser feito com os próprios métodos.

  2. A função deve poder referenciar variáveis livres. Qualquer variável referenciada pela função que não seja local - incluindo os parâmetros - é uma variável livre. No exemplo do enantiomero, a variável ascending é livre. Se ela não puder ser acessada pela função, então essa função não pode ser considerada closure.

  3. Os valores das variáveis livres que a função usa devem ser determinados de acordo com o contexto, como falou o enantiomero. Se o método sort for executado duas vezes, e em cada uma das vezes a variável livre ascending possuir valor diferente, ele deve ser sensível a essa mudança.