2010-11-29 12 views
9

El compilador de Scala compila directamente el código de bytes de Java (o .NET CIL). Algunas de las características de Scala podrían volver a realizarse en Java de forma directa (por ejemplo, sencillas para comprensión, clases, traducción anónima/función interna, etc.). ¿Cuáles son las características que no se pueden traducir de esa manera?¿Qué características de Scala no se pueden traducir a Java?

Eso es, presumiblemente, mayormente de interés académico. Más útil, tal vez, ¿cuáles son las características o expresiones idiomáticas de Scala que USTED usa que no se pueden representar fácilmente en Java?

¿Hay algo al revés? ¿Qué cosas se pueden hacer de manera directa en Java que no tienen un equivalente directo en Scala? Modismos en Java que no se traducen?

+0

Buena pregunta con buenas respuestas. Parece que al comparar Scala con Java, la gente finalmente obtiene que todos los idiomas son igualmente potentes, pero ofrecen diferentes abstracciones que tienen diferentes (des) ventajas. – Raphael

Respuesta

10

Esta pregunta, en mi opinión, no tiene sentido al pedirnos que comparemos los lenguajes JVM mirando su código de bytes generado.

Scala compila en bytecode equivalente a Java. Es decir, el bytecode podría haber sido generado por un código escrito en Java. De hecho, incluso puede obtener scalac para generar una forma intermedia que se parece mucho a Java.

Todas las características como rasgos (a través de los transitarios estáticas), los rendimientos no locales (a través de excepciones), los valores de descanso (a través de referencias), etc son todos expresable mediante un programa en Java, aunque posiblemente en forma más feo!

Pero lo que hace Scala Scala y no Java es lo scalac puede hacer por usted, antes de generar el código de bytes. Lo que scalac tiene a su favor, como lenguaje estático, es la capacidad de verificar la corrección de un programa, incluida la corrección de tipo (de acuerdo con su sistema de tipo ) en tiempo de compilación.

La principal diferencia entonces entre Java y Scala (como, por supuesto, Java también se escribe de forma estática), por lo tanto, es el sistema de tipo de Scala, que es capaz de expresar las relaciones programáticas que sistema de tipos de java-la-lengua no puede .Por ejemplo:

class Foo[M[_], A](m : M[A]) 
trait Bar[+A] 

Estos concepto, que M es un parámetro de tipo que a su vez tiene el tipo de parámetros, o que Bar es covariante, simplemente no existen en Java-tierra.

+0

¿Hubiera pensado que no es necesario que todas las posibilidades de código de bytes de Java se puedan generar a partir de un programa fuente de Java? Por lo tanto, puede haber casos en que Scalac pueda generar esa javac cannnot, y viceversa. –

+0

Eso es cierto, pero scala ha tomado específicamente * no * esta ruta. Casi todo el byte que emite Scala podría haber sido emitido desde un programa Java. Pero el punto fundamental es que no son los * bytes * los que definen scala y lo que Scala puede hacer por usted –

+0

de acuerdo. Sin embargo, tengo curiosidad acerca de las diferencias (Antecedentes: conozco (muy) poco Java, y estoy aprendiendo sobre Scala. Hasta ahora, me gusta lo que sé de Scala, pero me pregunto cuánta frustración me estoy creando. para cuando regrese a Java. Es como cuando aprendí Lisp - eso cambió la forma en que escribí en todos los idiomas, pero algunas cosas en Lisp son casi imposibles en lenguajes como C. –

11

Los rasgos son una cosa que no tiene equivalente. Los rasgos son interfaces con código en ellos. Puede copiar el código en todas las clases que tienen un rasgo mezclado, pero eso no es lo mismo.

También creo que el sistema de tipo scala es más completo. Mientras que finalmente se asignará a los tipos de JVM (en realidad sufren borrado). Puede expresar algunas cosas en el sistema de tipo Scala que pueden no ser posibles en Java (como varianzas).

4

Creo que no existe un equivalente para mezclar dinámicamente algunos Rasgos. En Scala puedes agregar al momento de crear nuevos objetos algunos rasgos, que están mezclados.

Por ejemplo, creamos un perro que tiene hambre y sed y un perro que simplemente está hambriento.

val hungryThirstyDog = new Dog with Hungry with Thirsty 
val onlyHungryDog = new Dog with Hungry 

No conozco una manera equivalente de hacer esto en Java. En Java, la herencia está estáticamente definida.

+0

¿Hay alguna manera de resolver el mismo problema de diseño en Java, usando alguna otra técnica? –

+0

@Paul Defina "resolver", "representar fácilmente", "expresar de forma natural", etc. Con respecto a la composición mixin, los problemas similares se manejan en Java utilizando composición de objeto (has-a) e inyección de dependencia, pero estas técnicas introducen dependencias innecesarias y/o requieren más repetitivo. –

+0

No voy por el camino de definir todos los términos. Asumiré que el lector puede interpretar. Gracias por la respuesta. –

4

Las conversiones implícitas no tienen un equivalente directo en Java.

+0

Pero presumiblemente los explícitos podrían hacerse? Por lo tanto, es una conveniencia (una muy útil, por cierto) más que una diferencia en la expresividad. Estoy interesado en explorar en qué medida Scala le permite expresar las cosas de forma más "natural" (para ciertos valores de "natural") –

+1

Cuando nos expresamos en un lenguaje natural, a menudo eludimos aspectos del contexto que se dan por sentados por Tanto el hablante como el oyente (en común). De manera similar, cuando programo en Scala encuentro bastante natural eludir los parámetros o las conversiones que son claros desde el contexto o por suposiciones predeterminadas. –

+0

Sí, un buen comentario. También estoy descubriendo eso sobre Scala . –

4

Una característica de scala que he encontrado un buen uso para es la reificación de tipo a través de Manifiestos. Como la JVM elimina toda la información de tipo de genéricos, scala le permite conservar esta información en variables. Esto es algo que Java reflection AFAIK no puede manejar, ya que no hay argumentos para escribir en bytecode.

El caso que los necesité fue coincidencia de patrón en un tipo de List. Es decir, tenía un objeto VertexBuffer que almacenaba datos en la GPU, que se podía construir a partir de una lista de flotantes o enteros. El código de manifiesto parecía aproximadamente así:

class VertexBuffer[T](data:List[T])(implicit m:Manifest[T]) { 
    m.toString.match { 
    case "float" => ... 
    case "int" => ... 
    } 
} 

This link enlaces a un blog con más información.

Hay muchas páginas SO con más información también, como this one.

+0

Por supuesto, puede requerir que la persona que llama pase explícitamente una 'Clase ' en Java. –

+0

O cualquier identificador como una enumeración. Scala's es más limpio, pero supongo que no es una gran diferencia. – nullspace

3

Tres palabras: tipos de mayor grado de emparejamiento.

0

Su tema no está claro si quiere decir Java el JVM o Java el idioma. Dado que Scala se ejecuta en la JVM, la q no tiene sentido, ya que todos sabemos que Scala se ejecuta en la JVM.

+0

Creo que ya está claro, pero para mayor claridad me refiero a Java el lenguaje –

+0

Entonces, por definición, es posible expresar cualquier construcción scala en java, incluso si hay mucho de boilterplate y ruidoso. –

+1

No, eso solo es cierto si hay un programa Java que puede producir todas las secuencias de código de bytes válidas. No tengo idea si eso es cierto, pero no es un hecho. Y usé la palabra "directo" en la pregunta. Java y Scala son equivalentes en que ambos son Turing completos, pero la expresividad, la claridad, etc. pueden diferir. Eso es lo que estaba buscando –

Cuestiones relacionadas