Scala vs. Java: ¿Por qué debo aprender Scala?
Publicado: 2022-03-11Es cierto que hay algo de verdad en la afirmación de que "Scala es difícil", pero la curva de aprendizaje bien vale la inversión. Algunas de las características más complejas del lenguaje (tuplas, funciones, macros, por nombrar algunas) finalmente facilitan al desarrollador escribir mejor código y aumentar el rendimiento al programar en Scala. Francamente, somos programadores, y si no somos lo suficientemente inteligentes para aprender un lenguaje que tiene cierta complejidad, entonces estamos en el negocio equivocado.
Scala es un lenguaje JVM con seguridad de tipos que incorpora programación orientada a objetos y funcional en un lenguaje extremadamente conciso, lógico y extraordinariamente poderoso. Algunos pueden sorprenderse al saber que Scala no es tan nuevo como pensaban, ya que se introdujo por primera vez en 2003. Sin embargo, es particularmente en los últimos años que Scala ha comenzado a desarrollar un seguimiento significativo. Lo que plantea la pregunta de "¿Por qué Scala?".
Este artículo examina las ventajas de Scala, especialmente en comparación con Java (ya que Scala está escrito para ejecutarse en JVM). Scala no es el único intento de crear un "mejor Java". Alternativas como Kotlin y Ceylon también han seguido ese camino, pero tomaron la decisión fundamental de permanecer muy cerca de la sintaxis del lenguaje Java, para minimizar la curva de aprendizaje. Esto puede parecer una gran idea, pero en última instancia es algo contraproducente, ya que lo obliga a permanecer dentro de una serie de esos mismos paradigmas de Java que fueron la razón para querer crear un "mejor Java" en primer lugar.
Por el contrario, Scala se creó específicamente con el objetivo de ser un mejor lenguaje , eliminando aquellos aspectos de Java que consideraba restrictivos, demasiado tediosos o frustrantes para el desarrollador. Como resultado, existen distinciones de código y cambios de paradigma que pueden dificultar un poco el aprendizaje temprano de la programación de Scala, pero el resultado es un lenguaje mucho más limpio y bien organizado que, en última instancia, es más fácil de usar y aumenta la productividad.
Scala vs. Java: ¿Cuál es realmente más complejo?
Si bien la simplicidad del lenguaje Java ha sido parte de su éxito, irónicamente, también ha contribuido a su complejidad. Claro, puede escribir casi cualquier cosa en Java, pero las líneas de código requeridas para hacerlo pueden ser abrumadoras. La programación en Scala, por otro lado, tiene una estructura un poco más compleja. Pero si puede escribir una sola línea de código un poco más compleja que reemplace 20 líneas "más simples" de Java, ¿cuál es realmente más compleja?
La verdad es que Java suele ser demasiado detallado. En Scala, el compilador es increíblemente inteligente, por lo que evita que el desarrollador tenga que especificar explícitamente las cosas que el compilador puede inferir. Compare, por ejemplo, este simple "¡Hola mundo!" programa en Java vs Scala:
Hola Mundo en Java:
public class HelloJava { public static void main(String[] args) { System.out.println("Hello World!"); } }
Hola Mundo en Scala:
object HelloScala { def main(args: Array[String]): Unit = { println("Hello World!") } }
Si bien no hay una gran distinción entre los dos idiomas aquí, Scala es menos detallado incluso en este ejemplo simple.
Para un ejemplo más práctico, echemos un vistazo a la creación de una lista simple de cadenas:
Java:
List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3");
Escala:
val list = List("1", "2", "3")
Ciertamente, hay algunos trucos en Java para acortar un poco el código, pero no en el uso estándar.
Ahora considere un caso en el que tenemos una lista de cadenas que son números, pero queremos convertir esa lista en una lista de números enteros:
Java:
List<Integer> ints = new ArrayList<Integer>(); for (String s : list) { ints.add(Integer.parseInt(s)); }
Escala:
val ints = list.map(s => s.toInt)
Gracias a las propiedades funcionales de Scala, esta conversión se vuelve extremadamente simple.
Un ejemplo de clase: Java vs. Scala
Vayamos un paso más allá y comparemos la creación de beans estándar/objetos Java simples (POJO) en Java y Scala.
Primero, la versión de Java:
public class User { private String name; private List<Order> orders; public User() { orders = new ArrayList<Order>(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } } public class Order { private int id; private List<Product> products; public Order() { products = new ArrayList<Product>(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } } public class Product { private int id; private String category; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
Uf. código de lotta.

Ahora la versión de Scala:
class User { var name: String = _ var orders: List[Order] = Nil } class Order { var id: Int = _ var products: List[Product] = Nil } class Product { var id: Int = _ var category: String = _ }
¿Qué idioma dijimos que era más complicado?
¿Estamos siendo justos?
Si ha llegado hasta aquí y es un programador de Java, en este punto puede estar pensando que estoy haciendo una comparación injusta de código. Después de todo, no hay nada que me impida crear variables públicas en Java y luego deshacerme de los getters y setters.
Sin embargo, si recuerda el razonamiento detrás de getters y setters en Java, es específicamente para prueba de futuro. Es decir, si luego necesita agregar algo de lógica a la obtención o configuración de variables, tendrá que volver a escribir esas variables públicas para usar métodos en su lugar (razón por la cual se recomienda el uso de getters y setters para empezar en Java ). Sin embargo, en la programación de Scala este no es el caso. Debido al diseño del lenguaje, la abstracción permanece intacta sin necesidad de getters y setters. Considere, por ejemplo, esta clase de User
modificada en Scala que arroja una NullPointerException
si intenta establecer el nombre en nulo:
class User { private var _name: String = _ var orders: List[Order] = Nil def name = _name def name_=(name: String) = { if (name == null) { throw new NullPointerException("User.name cannot be null!") } _name = name }
Y aún puede establecer el nombre de esta manera:
user.name = "John Doe"
Tenga en cuenta que esto elimina por completo la necesidad de preconfigurar métodos de acceso.
Además, dado que Scala prefiere la inmutabilidad, puedo escribir esto en Scala de manera aún más concisa con clases de casos:
case class User(name: String, orders: List[Order]) case class Order(id: Int, products: List[Product]) case class Product(id: Int, category: String)
Bastante loco cuánto menos código tengo que escribir.
Llevando el ejemplo un poco más lejos
Ahora considere un escenario con las clases anteriores donde quiero agregar un pequeño método ingenioso en la clase User
que devuelve una lista de todos los Products
que el User
ha pedido:
En el mundo detallado de Java:
public List<Product> getProducts() { List<Product> products = new ArrayList<Product>(); for (Order order : orders) { products.addAll(order.getProducts()); } return products; }
Afortunadamente, java.util.List
tiene un método addAll
, o getProducts()
hubiera sido incluso más largo en Java.
En Scala, por otro lado, todo lo que necesitamos es:
def products = orders.flatMap(o => o.products)
Puede ver cuánto más pequeña es la implementación del lenguaje Scala. Sí, puede parecer más complejo para el novato de Scala, pero una vez que comprenda completamente los conceptos detrás de él, el código de Scala parecerá mucho más simple que el código de Java.
Vamos a complicarnos un poco más aquí. ¿Qué pasa si solo queremos obtener los Products
dentro de una Category
específica?
En este caso, no podemos aprovechar el método addAll
en java.util.List
, por lo que las cosas se ponen más feas en Java :
public List<Product> getProductsByCategory(String category) { List<Product> products = new ArrayList<Product>(); for (Order order : orders) { for (Product product : order.getProducts()) { if (category.equals(product.getCategory())) { products.add(product); } } } return products; }
En Scala , sin embargo, el código sigue siendo bastante sencillo. Simplemente usamos flatMap
para combinar las listas de productos de cada Order
aplanado en una sola lista, luego filtramos para incluir solo los que coinciden con la categoría:
def productsByCategory(category: String) = orders.flatMap(o => o.products).filter(p => p.category == category)
Dinámico vs estático
Ciertamente, no ha habido escasez de nuevos lenguajes en los últimos años, pero mientras que casi todos los demás que han surgido recientemente son dinámicos, Scala tiene tipos estáticos.
Como desarrollador profesional, aunque conozco y uso muchos lenguajes dinámicos, en mi opinión, las comprobaciones en tiempo de compilación son increíblemente importantes para escribir código sólido. En un lenguaje dinámico, nunca puede estar seguro de que su código esté lo suficientemente libre de errores y sea robusto hasta que realmente lo ejecute en una amplia gama de escenarios. Esto puede generar defectos potencialmente graves en el código que nunca se detectan hasta que el código está en producción.
Envolver
Con suerte, este artículo compara Java vs. Scala lo suficiente como para darle una idea preliminar del poder y las capacidades de Scala y despertar su apetito por aprender el lenguaje. No solo es un gran lenguaje que puede hacer que la programación sea menos tediosa y más agradable, sino que también lo utilizan algunas de las empresas más grandes del mundo (LinkedIn, Twitter, FourSquare, The Guardian, por nombrar solo algunas).
La popularidad y el uso de Scala aumentan rápidamente, como lo demuestra el número cada vez mayor de puestos vacantes para desarrolladores de Scala. Si aún no lo ha hecho, ahora sería un buen momento para comenzar a montar la ola y dejar de preguntarse "¿Por qué aprender Scala?"