Quais são os benefícios e as desvantagens nas abordagens de C #, Java e Scala para Closures / Lambdas /…?


30

Gostaria de saber quais são as diferenças técnicas de implementação entre C # e Scala e como as duas soluções se comparam às idéias e preocupações de implementação expressas no email Peek Past lambda de Brian Goetz, enviado à lista de discussão do Project Lambda (JSR 335) ?

Do email:

Exploramos o caminho de "talvez lambdas devessem ser apenas instâncias de classe interna, isso seria realmente simples", mas finalmente chegamos à posição de "funções são uma direção melhor para o futuro da linguagem".

e ainda mais:

A visão lambdas-são-objetos do mundo entra em conflito com esse possível futuro. A visão lambdas-são-funções do mundo não existe, e preservar essa flexibilidade é um dos pontos a favor de não sobrecarregar as lambdas com a aparência de objeto.

Conclusão:

Lambdas-são-funções abre portas. Lambdas são objetos os fecha.
Preferimos ver aquelas portas abertas.

E algum comentário de uma pessoa no tópico do Reddit diz:

Na verdade, enviei um e-mail a Neal Gafter sobre isso e para meu entendimento limitado de sua explicação C # e o design atual do Java é bastante semelhante, pois os Delegados são na verdade objetos e não tipos de funções. Parece que ele acredita que Java deve aprender com as desvantagens das lambdas de C # e evitá-las (assim como o C # aprendeu com as desvantagens de Java e as evitou no início).

Por que a abordagem "Lambdas são funções" possibilita mais oportunidades no futuro do que "Lambdas são objetos"? Alguém pode explicar quais diferenças existem e como elas influenciam a forma como o código seria escrito?

Vendo que as coisas no Scala "simplesmente funcionam", continuo pensando que estou perdendo algo sobre as abordagens adotadas / propostas em C # / Java (8), provavelmente está relacionado a preocupações sobre compatibilidade com versões anteriores?


11
Isto é interessante. Dado que o sistema do tipo Javas não tem conceito de funções a partir de agora, isso significaria que era necessário introduzi-lo primeiro. É possível que o idioma se torne muito complexo com isso.
Ingo

As funções não são instâncias de alguma interface? O que há de tão especial neles?
soc

Lisp / Scheme / Clojure pode modelar objetos enquanto Java / C # não pode modelar o aninhamento arbitrário de funções. Python parece ter o melhor dos dois mundos, no entanto.
Job

Respostas:


15

Eu acho que a discussão sobre objetos versus funções é um arenque vermelho. Se a pergunta for: "Um lambda é uma função ou um objeto?" a resposta deve ser sim .

Esse é o objetivo das funções de primeira classe: elas não são tratadas de maneira diferente de qualquer outro tipo. O Java já consegue ignorar principalmente as diferenças entre os tipos Object e primitivo (e Scala se sai melhor ainda), portanto, se um lambda é uma subclasse de Object ou se é um novo tipo primitivo ou algo mais não é realmente importante para a linguagem. O importante é que você pode colocar suas lambdas em coleções, passá-las para serem chamadas, chamá-las e fazer qualquer outra coisa que você queira fazer com um objeto ou método.

O Scala realiza isso usando um objeto wrapper que possui um método chamado applyque pode ser chamado justamente (), fazendo com que pareça uma chamada de método. Isso funciona esplendidamente; Na maioria das vezes, você nem precisa se preocupar se possui um método ou está chamando a aplicação de um objeto de função.


9

Pelo que entendi, é mais sobre como as lambdas são consideradas no nível do idioma principal. Como o email diz,

Você pode pensar que o design atual está fortemente vinculado a uma caixa de objeto para lambdas - tipos SAM - tornando-os efetivamente objetos de qualquer maneira. Mas isso foi cuidadosamente escondido da área da superfície, de modo a nos permitir considerar lambdas 'nuas' no futuro, ou considerar outros contextos de conversão para lambdas, ou integrar lambdas com mais rigidez às construções de controle. Não estamos fazendo isso agora e nem sequer temos um plano concreto para fazê-lo, mas a capacidade de fazer isso no futuro é uma parte crítica do design.

Eu acho que resume bem a sua pergunta. Se você declarar que "lambdas são objetos", então eles são apenas um objeto de uma classe específica e você está preso a isso. Por outro lado, se você declarar "lambdas são funções", semanticamente você terá um campo de jogo muito mais rico. O Java 1.7 pode compilá-los em objetos, para que sejam praticamente idênticos nesse ponto.

Mas o Java 1.8, ou 1.9, pode trazer mudanças na linguagem (como tipos estruturais reificados) do que permitir que funções sejam usadas de maneiras muito mais flexíveis. Se "lambdas fossem objetos", essas alterações não seriam compatíveis com versões anteriores e você teria que introduzir um novo conceito ainda mais, para não quebrar o código existente das pessoas. Mas, se javacapenas silenciosamente convertendo lambdas em objetos nos bastidores, o novo javacpode convertê-los para o que quiser, desde que a semântica ainda seja válida.


lamdas em C #! = dos delegados. O compilador tem a opção de compilá-los para delgates ou árvores de expressão. ambos são de fato gráficos de objetos, mas eles não são compilados para uma "classe especial" nem mesmo uma classe de uma árvore de herança especial
Rune FS

Se eu entendi corretamente, compilar o lambda em uma classe interna do objeto associado a ele vincula-o a esse objeto; portanto, no futuro, se o Java introduzir funções de ordem superior (funções no mesmo nível de objetos), então você não poderia usar a implementação da classe interna, e haveria uma inconsistência. Eu não acho que o Java terá funções de ordem superior tão cedo.
precisa saber é o seguinte

@mwolfetech: Até onde eu sei, eles já estão planejados para o Java 8 com métodos de defesa. Eles querem adicionar coisas como foreach, map, filteràs coleções.
soc

@soc Bom ponto, é difícil acompanhar o número de JSRs e se eles realmente serão concluídos e criarão uma versão de destino do JDK. Parece que os métodos de defesa podem fazer parte do mesmo JSR. Com relação a este JSR , achei o post State of the Lambda de Brian Goetz útil - explica os tipos de SAM e os pensamentos atuais para implementar expressões lambda.
Mwolfetech

"pensamentos atuais" mhhh, esse post de 2010 não está obsoleto agora?
soc

5

Principalmente, ele simplesmente não quer se comprometer muito cedo com alguma coisa. Não vejo nenhuma razão além do apagamento que ele apresentou, mas essa é realmente uma razão muito forte.

Eu não gosto de tipos de função - eu amo tipos de função -, mas esses tipos de função tiveram um grande problema com um aspecto existente do sistema de tipos Java, o apagamento. Tipos de funções apagadas são os piores dos dois mundos.

Considere estes métodos no Scala Regex:

def replaceAllIn (target: CharSequence, replacer: (Match)  String): String
def replaceSomeIn (target: CharSequence, replacer: (Match)  Option[String]): String

Seria mais simples se eles fossem simplesmente isso:

def replace (target: CharSequence, replacer: (Match)  String): String
def replace (target: CharSequence, replacer: (Match)  Option[String]): String

Infelizmente, isso não é possível, porque essas duas funções são idênticas sob apagamento. Mas tudo bem, essas funções fazem coisas um pouco diferentes; portanto, um nome diferente pode ser justo o suficiente.

No entanto, a Matché algo muito útil, mas na maioria das vezes você deseja a correspondência Stringou a lista de subgrupos. Gostaríamos de ter o seguinte:

def replaceAllIn (target: CharSequence, replacer: (String)  String): String
def replaceAllIn (target: CharSequence, replacer: (Seq[String])  String): String
def replaceAllIn (target: CharSequence, replacer: (Match)  String): String

Não é possível, por causa do apagamento. Eu escolhi esse exemplo em particular porque estava diretamente envolvido com ele, mas já vi pelo menos meia dúzia de perguntas no Stack Overflow, onde as pessoas perguntam por que uma sobrecarga é ilegal, causada por esse problema exato.

E, então, considere que a correspondência de padrões do Scala e do Java instanceofsão efetivamente inúteis por causa do apagamento.

Eu acho que é justo adiar os tipos de função até que esse problema seja resolvido. Afinal, existem muitas linguagens na JVM, e não é como se o Java fosse uma linguagem em rápida evolução.


Bem, se o apagamento de tipo é o único problema que eles têm, o que planejam fazer? Quebrando todos os códigos neste planeta foi governado um não-opção para Java 5 já ...
soc

@ soc Estou tão feliz por não estar no lugar deles! Mas isso era Sun, isso é Oracle. A Oracle nunca teve nenhuma dificuldade em fazer alterações significativas entre as principais e até as menores versões de seu principal produto.
Daniel C. Sobral

Talvez eles devam mudar o nome do idioma e começar a desenvolver um novo idioma, diminuindo a compatibilidade com versões anteriores. Portanto, alguém teria os benefícios de um novo idioma sem a necessidade de brincar com um idioma mais antigo e bem estabelecido. Afinal, foi isso que Scala e Clojure fizeram.
Giorgio

@Giorgio Isso seria um pouco inútil. Bem, algumas das pessoas que são responsáveis pelo que Java é hoje fez isso, mas, como você disse, não são alternativas. Mas as pessoas responsáveis ​​pelo Java precisam melhorar o próprio Java - afinal, são responsáveis por isso. A única alternativa é simplesmente descartar o Java e renunciar a todos os benefícios resultantes do controle.
Daniel C. Sobral

@ Daniel C. Sobral: A IMO, uma linguagem de programação, é um pouco como um software: no começo, pode ser limpa e bem projetada, mas quanto mais você brinca com ela, mais fica bagunçada. Então, acho que seria do interesse dos desenvolvedores congelar o Java como linguagem e concentrar o desenvolvimento em (1) criar novas bibliotecas ou melhorar as existentes, (2) melhorar a JVM (se possível), (3) desenvolver novas linguagens . Mas, como você disse, há pessoas responsáveis ​​pelo Java e que desejam continuar vendendo atualizações. Então eles vão estendê-lo para mantê-lo "legal". Apenas meus 2 centavos.
Giorgio
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.