Por que não delegates no estilo .NET em vez de encerramentos em Java?

OK, este vai ser o meu cavalo a morrer pela terceira vez.

No entanto, esta questão é diferente dos meus dois primeiros sobre encerramentos / delegates, que pergunta sobre planos para delegates e quais são as especificações projetadas e implementação para fechamentos.

Esta questão é sobre – por que a comunidade Java está lutando para definir 3 tipos diferentes de encerramentos quando podemos simplesmente roubar todo o conceito de delegates: bloqueio, estoque e barril de nosso vizinho querido e amigável – a Microsoft.

Há duas conclusões não técnicas que eu gostaria de mergulhar:

  1. A comunidade Java deve manter seu orgulho, ao custo de precisar ir em esforços complicados, não sucumbindo a qualquer conceito da Microsoft ou reivindicando o brilhantismo da Microsoft.
  2. Delegados é uma tecnologia patenteada da Microsoft.

Tudo bem, além das duas possibilidades acima,

Q1 Existe alguma fraqueza ou inadequação nos delegates no estilo .NET que as três (ou mais) formas de fechamento abordariam?

Q2 Eu estou perguntando isso enquanto mudo entre Java e C # e me intriga que delegates C # faz exatamente o que eu precisava. Existem resources que seriam implementados em encerramentos que não estão atualmente disponíveis em delegates C #? Em caso afirmativo, quais são eles porque não consigo ver o que preciso mais do que os delegates C # me forneceram adequadamente?

Q3 Eu sei que uma das preocupações sobre a implementação de closures / delegates em java é a redução da ortogonalidade da linguagem, onde mais de uma maneira é exposta para executar uma tarefa específica. Vale a pena o nível de convolução e o tempo gasto para evitar delegates apenas para garantir que o java mantenha seu nível de ortogonalidade? No desenho relacional, sabemos que é aconselhável quebrar a ortogonalidade satisfazendo com frequência adequada apenas a segunda forma normal. Por que o java não pode ser submetido a redução de ortogonalidade e OO-ness por simplicidade?

Q4 A arquitetura da JVM é tecnicamente restrita pela implementação de representantes estilo .NET. Se esta razão (subjuntivo para enfatizar improbabilidade) for verdadeira, então por que as três propostas de fechamento não podem ser escondidas atrás de uma simples palavra-chave ou anotação de delegado: se não gostamos de usar @delegate, poderíamos usar @method. Não consigo ver como o formato de instrução delegada é mais complexo do que as três propostas de fechamento.

Sua pergunta é irônica. Você está se perguntando por que a comunidade Java está lutando com três propostas diferentes para adicionar closures, e sua solução sugerida é adicionar uma quarta opção ao mix?

Mas para responder sua pergunta:

  • O fórum certo para discussão é a lista de discussão do lambda do projeto openjdk. Este não é um lugar onde as sugestões possam influenciar esse esforço.

  • Os sistemas de tipos para C # e Java são significativamente diferentes, portanto, a solução C # não se aplicaria diretamente. Por exemplo, C # tem variância de site de declaração (in / out), enquanto java tem variância de site de uso (curingas). A inferência de tipos de parâmetro lambda, conforme especificado em C #, não se aplicaria em Java.

  • A evolução do Java deve permanecer compatível com versões anteriores, mas adicionar a palavra-chave delegada seria uma alteração urgente.

  • O C # tem três tipos de expressões delegadas: a antiga com a palavra-chave delegate, a instrução lambdas com => {e a expressão lambdas. Se a equipe de idiomas C # fizer isso novamente, certamente não teríamos muitas formas. Por que Java deveria adotar a bagagem histórica do C #?

  • Como os genéricos C # operam sobre primitivos, os tipos de delegação Func <> e Action <> podem ser usados ​​como tipos de funções estruturais de pessoas de baixa renda. Mas, em Java, os genéricos são apagados, funcionam apenas sobre tipos de referência e os tipos não podem ser distinguidos por sua aridade. Consequentemente, o Java teria que ter um grande número de tipos de function “padrão” com nomes distintos para obter o mesmo efeito. Isso não seria bonito.

No geral, a solução C # não se adapta a uma solução muito natural em Java.

C # tem encerramentos além de delegates. Na minha cabeça eles não são iguais.

delegate = ponteiro de function.

fechamento = {function, ambiente}. Forma de definir uma function [anônima] e empacotá-la com seu ambiente. Estritamente falando, esta última só deveria ser chamada de fechamento, a primeira sendo “expressão lambda”.