Como o novo desenvolvimento do Java influenciará sua interoperabilidade com linguagens como Scala e Clojure?

11

Tanto quanto eu entendo, Scala e Clojure foram projetados como novos idiomas que

  1. dependem da JVM e
  2. integram-se facilmente ao código Java, no sentido em que permitem o uso de classes Java no código Scala e Clojure.

Começando com o Java 8 (e talvez ainda mais fortemente com as versões subseqüentes do Java), haverá mudanças na semântica da linguagem Java.

Eu queria perguntar como essas mudanças afetarão a interoperabilidade entre Java e Scala / Clojure e quais serão as consequências. Por exemplo, como os lambdas no Java 8 não são objetos (veja, por exemplo, aqui ), Scala e Clojure podem precisar lidar com valores Java que não são objetos. Isso seria um problema?

Eu posso pensar nos seguintes cenários:

  1. A linguagem Scala ou Clojure será estendida para se adaptar à nova semântica Java (para manipular os novos valores não-objeto) e oferecer suporte à interoperabilidade com Java.
  2. O idioma Scala ou Clojure não será estendido. Isso só seria possível se os novos recursos Java, como valores de função, pudessem ser mapeados para conceitos existentes. Por exemplo, no Scala, mesmo uma função é um objeto, então acho que as funções Java seriam novamente envolvidas em algum tipo de objeto quando elas se tornassem visíveis ao Scala.
  3. A linguagem Scala ou Clojure continuará a suportar interoperabilidade até Java 6 ou 7, sem seguir o desenvolvimento mais recente do Java. Isso exigiria que versões mais antigas do Java ainda sejam suportadas (pelo menos pelo OpenJDK ou outro projeto), para que essas linguagens possam se basear em um ramo mais conservador / estável do Java.

Resumindo: podemos esperar que o desenvolvimento futuro de Java tenha impacto em linguagens como Scala e Clojure para manter a interoperabilidade com Java? Já existe alguma (link para) discussão em andamento sobre esse tópico?

Nota

Posso imaginar que Scala, Clojure e outras linguagens baseadas em JVM não terão grandes problemas ao atualizar sua implementação para versões mais recentes da JVM (e que os novos recursos da JVM tornarão essa implementação ainda mais fácil). Minha pergunta se concentra nos recursos do Java como uma linguagem e se / como outra linguagem da JVM poderá "ver" / usar esses novos recursos, não se as linguagens baseadas na JVM serão executadas nas mais recentes JVMs.

Giorgio
fonte
6
É impreciso dizer que Scala etc. depende de Java. Eles dependem do código de bytes da JVM. Todos os recursos de interoperabilidade lidam com bytecode, não com o código-fonte da linguagem Java, portanto, quaisquer alterações feitas no próprio Java não são uma ameaça. Somente as alterações feitas na JVM podem afetar esses idiomas, e a JVM é extremamente conservadora - basicamente nunca remove o suporte para nada. Na verdade, a maioria das mudanças na JVM hoje em dia são destinados especificamente para as linguagens dinâmicas mais recentes.
Kilian Foth
@Kilian Foth: Até onde eu sei, um Scala Stringé um Java String. Portanto, o Scala usa certas classes de bibliotecas Java. Mas posso mudar a formulação se você achar que é muito forte.
Giorgio
@Kilian Foth: Eu removi o termo dependem porque o foco da minha pergunta está na interoperabilidade entre Scala e Java resp. Clojure e Java.
Giorgio
@KilianFoth Esta deve ser uma resposta, pois aborda a principal preocupação da pergunta. O objetivo número um de qualquer nova versão do Java é a compatibilidade com versões anteriores.
Maple_shaft
3
@ maple_shaft: Corrigi minha pergunta e removi a palavra "depend". Como indiquei em outro comentário, meu problema não é como o Scala ou o Clojure dependem dos recursos Java ou JVM, mas como o Scala / Clojure pode "ver" os recursos Java. Tanto quanto sei, eles podem ver recursos do Java 6, como classes, interfaces, objetos, métodos, tipos de dados primitivos. Isso permite que o Scala / Clojure use (chame) o código Java 6. Minha pergunta é: essas linguagens também "verão" (e, portanto, poderão usar) futuras construções da linguagem Java ou isso exigiria extensões das linguagens Scala / Clojure?
Giorgio

Respostas:

15

Na verdade, o Java 8 não introduz muita coisa que será prejudicial para outras linguagens da JVM que interoperam com o Java. O trabalho realizado no Lambdas ajudou a corrigir uma série de pequenos problemas em torno de invokedynamic, MethodHandles, MethodReferences etc. - mas, além disso, ele continua normalmente. Dito isso, há um monte de APIs totalmente novas que as outras linguagens da JVM poderiam potencialmente chamar agora. Quais eles usarão por padrão ou não, depende deles.

A maior interoperabilidade que impactou as mudanças ocorreu com o Java 7 - com o bytecode invocado dinâmico que permite chamadas de ligação dinâmica / tardia na JVM - algo que foi projetado inicialmente para os outros idiomas da JVM. Desde então, foi muito útil para o Lamdbas; assim, a partir do Java 8, o Java começará a emitir esses bytecodes.

Algumas linguagens (JRuby, por exemplo) já usam muito o invokedynamic, enquanto outras (Scala, Groovy et al) ainda estão investigando seu uso ou estão nos estágios iniciais de aplicação. Em teoria, as chamadas dinâmicas são quase tão eficazes quanto as existentes. Chamadas invocadas por Java, em oposição à miríade de soluções mais lentas que elas foram forçadas a usar no passado.

O Java 9 trará mais desafios para as linguagens da JVM, com o projeto Jigsaw chegando à plataforma, que será o começo do fim dos tradicionais carregamentos de classe e caminhos de classe para a JVM. O pessoal da linguagem JVM está bem ciente disso e espero que ocorra alguma colaboração sensata.

Martijn Verburg
fonte
1
Mas, tanto quanto eu sei, um fechamento do Scala é um objeto.
Giorgio
1
Sim. Recentemente, o Scala abandonou o suporte ao Java 1.5, e demorará muito tempo até o lançamento do 1.6.
Jörg W Mittag
1
@ Giorgio Os recursos de linguagem do Java são irrelevantes, pois a maioria deles equivale a truques de bytecode quando compilados de qualquer maneira. Se aceitarmos que a JVM sempre será compatível com versões anteriores, mesmo se novos códigos de código forem introduzidos, o Scala não será afetado e poderá optar por tirar proveito desses novos recursos da JVM conforme sua conveniência.
Maple_shaft
1
"Os recursos de linguagem do Java são irrelevantes, pois a maioria deles equivale a truques de bytecode quando compilados de qualquer maneira.": Se outra linguagem quiser usar uma construção Java, ela deve ser capaz de reconhecer o bytecode gerado para essa construção. Se o Java introduzir uma nova construção que mapeie para o novo bytecode, a linguagem do host deverá pelo menos implementar um novo wrapper / interface para reconhecer e usar o novo bytecode. Por exemplo, se um Java 8 lambda não criou um objeto, mas alguma nova construção com novo código de bytes específico para ele, a linguagem do host deve ser adaptada para reconhecê-lo.
Giorgio
2
@Giorgio: Claro, mas nenhuma dessas mudanças está planejada para a plataforma Java 8. De fato, o JVMS foi estendido apenas duas vezes em toda a história da Plataforma Java, em 2003 e 2010, e a segunda vez (introdução do invokedynamicbytecode) foi especificamente para suportar outras linguagens além do Java; de fato, a linguagem Java 7 não suporta ou usa esse bytecode.
Jörg W Mittag
2

O Scala está prestes a ser deixado para trás quando o Java adiciona lambdas porque o Java lambdas recebe um tipo de acordo com o contexto em que é usado, enquanto o Scala lambdas recebe um tipo com base em suas áreas, tipos de parâmetros e tipos de retorno, por exemplo,

executor.execute(() -> { System.out.println("hello world"); });

do Java 8 pode ser escrito em Scala como:

executor execute new Runnable {
    override def run() { println("hello world") }
}

a menos que você use / grave alguns wrappers convertendo Scala's () => Unit em Runnable.

Ricky Clarkson
fonte
Obrigado pela resposta e também por responder à minha pergunta (+1). Se eu entendi direito, o Scala precisará continuar usando classes anônimas para instanciar interfaces em um contexto no qual o Java 8 usará lambdas (porque o Java 8 lambdas tem uma semântica diferente da do Scala lambdas). Outro ponto que não está claro para mim é o que acontecerá se um método Java retornar um Java lambda. O que acontece se uma classe Scala chama esse método? Qual será o tipo de retorno no Scala?
Giorgio
1
@Giorgio No Java 8, uma expressão lambda é um atalho no nível da linguagem para criar uma instância da interface que declara um único método e que é adiada pelo contexto. Portanto, quando um método Java 8 retorna um lambda, ele realmente retorna uma instância da interface que é declarada como o tipo de retorno do método. No Scala 2.9.1, o tipo de retorno será simplesmente uma instância de alguma interface, digamos (Runnable ou Comparator), que você não pode tratar como um lambda do Scala, a menos que você ou as versões futuras da biblioteca do Scala introduzam uma conversão implícita a partir dessa interface. interface para o tipo lambda Scala.
hellodanylo
@SkyDan: Ok, então o Scala verá o Java lambdas como objetos implementando alguma interface. Este ponto não estava claro para mim: pensei que o Java geraria algum bytecode que fosse diferente daquele de um objeto. Mas deve ser um objeto oculto, caso contrário não seria reconhecido como a implementação de uma interface. Eu acho que entendi agora.
Giorgio
@Giorgio, também se você quiser saber mais sobre as mudanças relacionadas ao lambda no Java 8 e as forças que as impulsionam, eu recomendo que você leia esta fascinante e detalhada visão geral do projeto Lambda .
hellodanylo
@SkyDan: Lendo agora. Parece-me que lambdas fazer representar objetos (mesmo que o tipo / interface é inferida a partir do contexto em que são definidos). Portanto, as informações fornecidas em mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… ("lambdas não são objetos") estão incorretas ou, pelo menos, enganosas.
Giorgio