
El máquina virtual java proporciona un tiempo de ejecución universal y de alto rendimiento para una gran cantidad de lenguajes populares más allá de solo Java. En este artículo, veremos las fortalezas características y los casos de uso comunes de cuatro de los lenguajes JVM más populares: Kotlin, Scala, Groovy y Clojure.
Kotlin
Kotlin es un lenguaje moderno que ha visto una oleada de entusiasmo por parte de los desarrolladores en los últimos años. Esta popularidad se debe en gran parte a su sintaxis altamente expresiva, que incluye orientación a objetos y programación funcional apoyo, pero no termina ahí. Kotlin es interoperable con Java e incluye herramientas multiplataforma y compilación en varios idiomas. Al igual que otros lenguajes JVM, puedes usar GraalVM para compilar Kotlin en binarios nativos para una implementación altamente optimizada con un excelente uso de recursos de inicio, parada y tiempo de ejecución.
En 2019, Google identificó a Kotlin como el lenguaje preferido para el desarrollo de Androidun voto de confianza que impulsó su popularidad entre los desarrolladores.
Otro factor en la fortaleza de Kotlin es su respaldo de JetBrains, el creador del IntelliJ IDE. JetBrains ha mantenido y perfeccionado Kotlin constantemente. Esa inversión ha asegurado la estabilidad de Kotlin y al mismo tiempo lo ha mantenido a la vanguardia de la innovación, cualidades que los desarrolladores aprecian.
Debido a que es 100% interoperable con Java, los desarrolladores y organizaciones de Java pueden adoptar Kotlin gradualmente. Es Es fácil para un desarrollador de Java sentirse cómodo con Kotlin.y viceversa. Tampoco es difícil tener ambos idiomas en la cabeza. Para los desarrolladores de Java experimentados, Kotlin parece una versión ampliada de Java. E incluso si no sabes Java, aún puedes convertirte en un experto en Kotlin.
Kotlin obviamente brilla para su uso en Android, pero también es popular en otras áreas, incluido el desarrollo del lado del servidor. Kotlin es ideal para desarrollar DSL (lenguajes específicos de dominio). Uno de ellos, Kotlin HTML DSL, es un potente lenguaje de plantillas del lado del servidor integrado para la web.
Uno de los activos más conocidos de Kotlin es su seguridad nula característica que permite minimizar la aparición de NullPointerExceptions. Tipos estándar como String no se puede inicializar nulla menos que lo permita explícitamente usando el modificador que acepta valores NULL (¿Cadena?). Cuando se utilizan tipos que aceptan valores NULL, el compilador no permite el acceso sin una verificación de seguridad. Kotlin también le ofrece el operador de punto seguro para nulos (?.), que es similar a la operador de cadena opcional en javascript. He aquí un vistazo a Kotlin usando el ?: operador para proporcionar un valor predeterminado al verificar:
val length = middleName?.length ?: 0
En este ejemplo, si middleName es nulo, length se pondrá a 0.
Otra característica excelente es corrutinasque proporciona una forma estructurada de gestionar operaciones simultáneas. Corrutinas de Kotlin están inspirados en Go's gorutinasy también fueron una inspiración para el nuevo Java modelo de concurrencia estructurada. Este ejemplo muestra cómo se puede utilizar una corrutina de Kotlin para proporcionar sintaxis síncrona para lógica asincrónica:
import kotlinx.coroutines.*
fun main() = runBlocking { // main coroutine
// Launch a new coroutine
launch {
delay(1000L) // suspend for 1 second
print("InfoWorld!") // Print after delay
}
print("Hello,") // The main coroutine continues
}
Sólo hemos arañado la superficie de las capacidades de Kotlin, pero estos ejemplos deberían darle una idea de por qué se ha vuelto tan popular entre los desarrolladores. Como lenguaje principal, Kotlin ha aumentado enormemente el poder y el alcance de la JVM.
Ver también: Kotlin para desarrolladores de Java.
escala
Scala se diferencia de otros lenguajes JVM al hacer que la programación funcional sea fundamental y al implementarla rigurosamente. Como resultado, los desarrolladores que prefieren la programación funcional y quieren aprovechar la JVM suelen recurrir a Scala. Aunque no se enfatiza, Scala también tiene un fuerte soporte para la programación orientada a objetos.
Scala es muy popular para el procesamiento de datos en tiempo real, de alto rendimiento y a gran escala. Es el lenguaje de chispa apachela plataforma distribuida para transmisión de big data, procesamiento por lotes, análisis, aprendizaje automático y más. El uso extensivo y excelente que hace Spark de la capacidad de Scala para unir flujos de eventos con operadores funcionales es otro poderoso impulsor para la adopción de Scala.
La coincidencia de patrones es una de las funciones de programación funcional más populares de Scala. A continuación se muestra un ejemplo de la sintaxis similar a un interruptor de Scala para el control de flujo:
case class Message(sender: String, body: String)
val notification: Any = Message("Ada Lovelace", "Hello, InfoWorld!")
notification match {
case Message(sender, body) => println(s"Message from $sender: $body")
case "Ping" => println("Received a Ping")
case _ => println("Unknown notification type")
}
Esto proporciona una sucursal si notification es un tipo de mensaje y nos permite definir una función que recibe las propiedades de ese mensaje. Si notification es un String que contiene «Ping», pasa al segundo caso y el carácter de subrayado define el valor predeterminado. La belleza de esta construcción es que todo sucede dentro del paradigma de programación funcional.
Escala también enfatiza la inmutabilidadotro principio de la programación funcional. Inmutabilidad hace que el software sea más sencillo y menos propenso a errores. En Scala, la palabra clave de declaración de variable principal es valque es una colección constante e integrada como List, Vectory Map son todos inmutables. Modificas las colecciones usando operaciones funcionales como filterque crean nuevas colecciones.
Scala también es muy fuerte en concurrencia, empleando actores en un potente sistema de programación de estilo reactivo. El modelo de actor de Scala constituye la base del renombrado marco akkaun conjunto de bibliotecas para informática distribuida multiproceso.
Scala también tiene un sistema de tipos sofisticado que admite casos de uso avanzados. He aquí un ejemplo de la tipo de rasgoque combina una clase abstracta y una interfaz. El tipo de rasgo permite que las clases desciendan de múltiples ancestros con miembros tanto abstractos como concretos:
trait Speaker {
def speak(): String
def announce(message: String): Unit = {
println(message)
}
}
class Dog extends Speaker {
override def speak(): String = "Woof!"
}
class Person(name: String) extends Speaker {
override def speak(): String = s"Hello, my name is $name."
}
@main def main(): Unit = {
val sparky = new Dog()
val ada = new Person("Ada")
println(s"The dog says: ${sparky.speak()}")
println(s"The person says: ${ada.speak()}")
ada.announce("I am learning about traits!")
}
Note que el Speaker El rasgo tiene métodos tanto concretos como abstractos, y las clases que lo extienden pueden extender más de un rasgo, lo que no es posible con una clase abstracta.
Por supuesto, hay más en Scala, pero estos ejemplos le dan una idea de ello.
maravilloso
Groovy es la alternativa JVM original. Es un lenguaje de programación altamente dinámico, popular por su sintaxis simple y de baja formalidad. Es el lenguaje de lo omnipresente. Administrador de compilación de Gradley a menudo se utiliza como lenguaje adhesivo o cuando una aplicación necesita puntos de extensión personalizables. También es bien considerado por su capacidad para definir DSL.
Para los desarrolladores que vienen de Java, Groovy se siente como una versión de Java a la que se le ha eliminado parte del texto estándar y la formalidad. Groovy es principalmente un superconjunto de Javalo que significa que la mayor parte de Java también es Groovy válido.
Groovy es también el lenguaje del Marco de prueba de Spock.
Groovy prescinde de los puntos y comas “innecesarios” y proporciona automáticamente variables no declaradas para scripts (conocidas como enlace de guión). Esto es especialmente útil para extensiones de aplicaciones y DSL, donde el lenguaje anfitrión (particularmente Java) crea un contexto para el script Groovy y los usuarios pueden crear funciones sin declarar variables.
Este ejemplo ofrece una muestra del sabor optimizado de Groovy:
def list = (1, 2, 3, 4, 5)
def doubled = list.collect { it * 2 }
println("Doubled: " + doubled) //-> Doubled: (2, 4, 6, 8, 10)
def evens = list.findAll { it % 2 == 0 }
println("Evens: " + evens) //-> Evens: (2, 4)
Aquí puede ver el manejo de colecciones de baja formalidad de Groovy, que se basa en programación funcional.
Otra de las características populares de Groovy es su escritura dinámica y opcional. Puede declarar un tipo de variable, pero no es necesario. Si no declara el tipo de variable, Groovy administrará la variable en función de cómo se utiliza, una técnica conocida como ducktyping. (JavaScript tiene una operación similar).
Finalmente, Groovy admite metaprogramaciónque es algo así como una versión más potente del API de reflexión de Java.
Clojure
Por último, pero no menos importante, Clojure es un descendiente de Lispun lenguaje fundamental utilizado en el aprendizaje automático y el procesamiento simbólico. Lisp ha influido en muchos idiomas y ocupa un lugar especial para los amantes de los idiomas, gracias a su combinación única de sintaxis expresiva pero simple y filosofía de «código como datos».
Código como datos, también conocido como homoiconicidadsignifica que el código se representa como estructuras de datos en el lenguaje. Esto abre oportunidades de metaprogramación porque la representación del código se puede cargar y manipular directamente como software.
El código como datos también crea posibilidades para macros potentes, donde la macro comprende la sintaxis del código que expande. Este enfoque de las macros es diferente de lenguajes como C, donde las macros son texto simple, lo que a menudo conduce a errores furtivos.
Aquí hay una función simple en la sintaxis similar a Lisp de Clojure:
;; Comments in Clojure use double semi-colons
(defn greet (name)
(str "Hello, " name "!"))
Los bloques entre paréntesis que ve son una característica del código que también son estructuras de datos. Los paréntesis indican una colección (una lista) y las funciones se definen y llaman usando una lista (por ejemplo, palabras clave, nombres de funciones, argumentos).
Clojure también es conocido por su sólido modelo de concurrencia, construido desde cero para simplificar la gestión del estado en múltiples subprocesos. El enfoque de Clojure en la inmutabilidad y el excelente soporte para las transiciones de estado administradas lo convierten en un lenguaje concurrente completo. Se centra en la inmutabilidad en lugar de orquestar estados mutables entre subprocesos, lo que dejaría lugar a errores. Clojure también incluye un modelo de agente reactivo para tratar con estado mutable y concurrencia.
Clojure es un lenguaje altamente estructurado y refinado. Es rigurosamente funcional en su filosofía y ofrece un poder significativo al desarrollador. Estas cualidades en el diseño y ejecución de Clojure lo han convertido en una opción muy respetada entre los programadores.
Conclusión
Los cuatro lenguajes descritos aquí son las estrellas del universo de lenguajes alternativos de JVM, pero hay muchos otros. En particular, existen versiones JVM de lenguajes convencionales, como jRubí y Jython.
Kotlin se ha convertido en un lenguaje dominante por derecho propio y recientemente entró en el top 20 de Tiobe. Pero los cuatro idiomas aportan fortalezas en áreas particulares. Y todos ellos demuestran el poder del propia JVM.
He aquí un vistazo a las características de alto nivel de los cuatro idiomas:
| Idioma | Paradigma | Curva de aprendizaje | Caso de uso asesino | Valores fundamentales |
| Kotlin | POO, funcional (pragmático) | Fácil | Aplicaciones de Android | Pragmatismo, seguridad |
| escala | Funcional, POO (riguroso) | Moderado | Big data (chispa) | Seguridad de tipos, escalabilidad |
| Clojure | Funcional (ceceo) | Duro | API centradas en datos | Simplicidad, inmutabilidad |
| maravilloso | Dinámico, secuencias de comandos | Fácil | Construcciones (Gradle) | Flexibilidad, secuencias de comandos |




