¿Cómo influirá el nuevo desarrollo de Java en su interoperabilidad con lenguajes como Scala y Clojure?

11

Por lo que yo entiendo, tanto Scala como Clojure han sido diseñados como nuevos lenguajes que

  1. dependerá de la JVM, y
  2. se integran fácilmente con el código Java, en el sentido de que permiten usar clases Java dentro del código Scala y Clojure.

Comenzando con Java 8 (y tal vez aún más fuerte con versiones posteriores de Java), habrá cambios en la semántica del lenguaje Java.

Quería preguntar cómo estos cambios afectarán la interoperabilidad entre Java y Scala / Clojure y cuáles serán las consecuencias. Por ejemplo, dado que las lambdas en Java 8 no son objetos (ver, por ejemplo, aquí ), Scala y Clojure podrían tener que lidiar con valores de Java que no son objetos. ¿Sería esto un problema?

Puedo pensar en los siguientes escenarios:

  1. El lenguaje Scala o Clojure se extenderá para adaptarse a la nueva semántica de Java (para manejar los nuevos valores no objeto) y admitir la interoperabilidad con Java.
  2. El lenguaje Scala o Clojure no se extenderá. Esto solo sería posible si las nuevas características de Java, como los valores de función, pueden asignarse a conceptos existentes. Por ejemplo, en Scala, incluso una función es un objeto, así que supongo que las funciones de Java volverían a estar envueltas en algún tipo de objetos cuando sean visibles para Scala.
  3. El lenguaje Scala o Clojure continuará admitiendo la interoperabilidad hasta Java 6 o 7, sin seguir el último desarrollo de Java. Esto requeriría que las versiones anteriores de Java aún sean compatibles (al menos con OpenJDK u otro proyecto), de modo que estos lenguajes puedan basarse en una rama más conservadora / estable de Java.

Resumiendo: ¿podemos esperar que el desarrollo futuro de Java tenga un impacto en lenguajes como Scala y Clojure para mantener la interoperabilidad con Java? ¿Hay alguna (enlace a) discusión en curso sobre este tema?

Nota

Me imagino que Scala, Clojure y otros lenguajes basados ​​en JVM no tendrán problemas importantes para actualizar su implementación a versiones más recientes de JVM (y que las nuevas características de JVM harán que esta implementación sea aún más fácil). Mi pregunta se centra en las características de Java como lenguaje y si / cómo otro lenguaje JVM podrá "ver" / usar estas nuevas características, no si los lenguajes basados ​​en JVM se ejecutarán en los últimos JVM.

Giorgio
fuente
66
Es impreciso decir que Scala, etc., depende de Java. Dependen del código de bytes JVM. Todas las funciones de interoperabilidad se ocupan de bytecode, no del código fuente del lenguaje Java, por lo que cualquier cambio que se realice en Java en sí no es una amenaza. Solo los cambios realizados en la JVM podrían afectar estos lenguajes, y la JVM es extremadamente conservadora: básicamente, nunca elimina el soporte para nada. De hecho, la mayoría de los cambios en la JVM hoy en día están destinados específicamente a los nuevos lenguajes dinámicos.
Kilian Foth
@Kilian Foth: Hasta donde yo sé, un Scala Stringes un Java String. Entonces Scala usa ciertas clases de biblioteca Java. Pero puedo cambiar la formulación si crees que es demasiado fuerte.
Giorgio
@Kilian Foth: he eliminado el término depender porque el foco de mi pregunta es más bien la interoperabilidad entre Scala y Java resp. Clojure y Java.
Giorgio
@KilianFoth Esto debería ser una respuesta porque aborda la principal preocupación de la pregunta. El objetivo número uno de cualquier nueva versión de Java es la compatibilidad con versiones anteriores.
maple_shaft
3
@maple_shaft: he corregido mi pregunta y eliminado la palabra "depender". Como señalé en otro comentario, mi problema no es cómo Scala o Clojure dependen de las características de Java o JVM, sino cómo Scala / Clojure puede "ver" las características de Java. Hasta donde yo sé, pueden ver características de Java 6 como clases, interfaces, objetos, métodos, tipos de datos primitivos. Esto permite que Scala / Clojure use (llame) el código Java 6. Mi pregunta es, ¿estos lenguajes también "verán" (y, por lo tanto, podrán usar) futuras construcciones de lenguaje Java o esto requeriría extensiones a los lenguajes Scala / Clojure?
Giorgio

Respuestas:

15

En realidad, Java 8 no introduce mucho que vaya en detrimento de otros lenguajes JVM que interaccionan con Java. El trabajo realizado en Lambdas ayudó a solucionar una serie de pequeños problemas relacionados con invocados dinámicos, MethodHandles, MethodReferences, etc., pero aparte de eso, continúa de manera normal. Dicho esto, hay un nuevo grupo de API que los otros lenguajes de JVM podrían llamar ahora. Los que usarán por defecto o no dependerán de ellos.

El cambio más grande que afecta la interoperabilidad en realidad se produjo con Java 7, con el código de byte dinámico invocado que permite llamadas de enlace dinámico / tardío dentro de la JVM, algo que inicialmente se diseñó para los otros idiomas en la JVM. Desde entonces, se ha adaptado muy útilmente para Lamdbas, por lo que a partir de Java 8, Java comenzará a emitir estos códigos de bytes.

Algunos lenguajes (JRuby, por ejemplo) ya utilizan mucho la invocabilidad dinámica, mientras que otros (Scala, Groovy et al.) Todavía están investigando su uso o están en las primeras etapas de su aplicación. En teoría, hace que sus llamadas dinámicas sean casi tan efectivas como las existentes. Llamadas invocaticas de Java, a diferencia de la miríada de soluciones lentas que se vieron obligadas a usar en el pasado.

Java 9 traerá más desafíos para los lenguajes JVM con el proyecto Jigsaw que entrará en la plataforma, que será el principio del fin para la carga de clases y los classpaths tradicionalmente para JVM. La gente del lenguaje JVM es muy consciente de esto y espero que tenga lugar una colaboración sensata.

Martijn Verburg
fuente
1
Pero, que yo sepa, un cierre de Scala es un objeto.
Giorgio
1
Sí. Scala solo recientemente dejó de admitir Java 1.5, pasará mucho tiempo hasta que caigan 1.6.
Jörg W Mittag
1
@Giorgio Las características del lenguaje de Java son intrascendentes, ya que la mayoría de ellas equivalen a trucos de bytecode cuando se compilan de todos modos. Si aceptamos que JVM siempre será compatible con versiones anteriores, incluso si se introducen nuevos bytecodes, entonces Scala no se verá afectado y puede optar por aprovechar esas nuevas características de JVM a su conveniencia.
maple_shaft
1
"Las características del lenguaje de Java son intrascendentes, ya que la mayoría de ellas equivalen a trucos de bytecode cuando se compilan de todos modos": si otro lenguaje quiere usar una construcción Java, debe ser capaz de reconocer el bytecode generado para esa construcción. Si Java introduce una nueva construcción que se asigna a un nuevo código de bytes, el idioma del host debería implementar al menos un nuevo contenedor / interfaz para reconocer y utilizar el nuevo código de bytes. Por ejemplo, si un Java 8 lambda no creó un objeto sino una nueva construcción con un nuevo código de bytes específico para él, el lenguaje anfitrión debe adaptarse para reconocerlo.
Giorgio
2
@Giorgio: Claro, pero no se planean tales cambios para la plataforma Java 8. De hecho, el JVMS solo se extendió dos veces en toda la historia de la Plataforma Java, en 2003 y 2010, y la segunda vez (introducción del código de bytes invokedynamic) fue específicamente para admitir idiomas distintos de Java; de hecho, el lenguaje Java 7 no admite ni utiliza ese código de bytes.
Jörg W Mittag
2

Scala está a punto de quedarse atrás cuando Java agrega lambdas porque a las lambdas de Java se les asigna un tipo de acuerdo con el contexto en el que se usan, mientras que a las lambdas de Scala se les asigna un tipo en función de sus aridades, tipos de parámetros y tipos de retorno, por ejemplo,

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

de Java 8 se puede escribir en Scala como:

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

a menos que use / escriba algunos contenedores que conviertan Scala's () => Unit a Runnable.

Ricky Clarkson
fuente
Gracias por la respuesta y también por abordar mi pregunta (+1). Si entiendo correctamente, Scala tendrá que seguir usando clases anónimas para crear instancias de interfaces en un contexto en el que Java 8 usará lambdas (porque las lambdas de Java 8 tienen una semántica diferente a las lambdas de Scala). Otro punto que no me queda claro es qué sucederá si un método Java devuelve un lambda Java. ¿Qué sucede si una clase Scala llama a ese método? ¿Cuál será el tipo de retorno en Scala?
Giorgio
1
@Giorgio En Java 8, una expresión lambda es un acceso directo a nivel de lenguaje para crear una instancia de interfaz que declara un método único y que se difiere según el contexto. Entonces, cuando un método Java 8 devuelve una lambda, en realidad devuelve una instancia de interfaz que se declara como el tipo de retorno del método. A partir de Scala 2.9.1, el tipo de retorno va a ser simplemente una instancia de algunos dicen que la interfaz (Ejecutable o Comparador) que se puede no tratar como lambda Scala, a menos que usted o futuras versiones de Scala Libary introducir una conversión implícita de ese interfaz al tipo de lambda Scala.
hellodanylo
@SkyDan: Ok, entonces Scala verá las lambdas de Java como objetos que implementan alguna interfaz. Este punto no estaba claro para mí: pensé que Java generaría un código de bytes diferente al de un objeto. Pero debe ser un objeto oculto, de lo contrario no se reconocería como la implementación de una interfaz. Creo que lo tengo ahora.
Giorgio el
@Giorgio, también si desea saber más sobre los cambios relacionados con lambda en Java 8 y las fuerzas que impulsan estos cambios, le recomiendo que lea esta descripción fascinante y detallada del proyecto Lambda .
hellodanylo
@SkyDan: Leyendo ahora. Me parece que lambdas hacen representar objetos (aunque el tipo / interfaz se infiere del contexto en el que se han definido). Por lo tanto, la información proporcionada en mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… ("las lambdas no son objetos") es incorrecta o, al menos, engañosa.
Giorgio