Hola colegas
No hace mucho tiempo, imprimimos el
libro de Odersky, Spoon y Wenners sobre Scala 2.12. Después de todo, a Scala 3 todavía está lejos.
El autor del artículo de hoy es Adam Worski, cofundador de SoftwareMill y un experimentado desarrollador de Scala. Obtuvo un interesante resumen de las fortalezas del lenguaje Scala moderno, que llamamos su atención.
Después de una
conferencia plenaria de Martin Odersky en ScalaDays, donde describió los planes para Scala 3 y una
conferencia plenaria de John de Goes en la conferencia Scalapeño sobre el futuro de
Scala , continúan las animadas discusiones en
la comunidad Scala . Además de las discusiones de estas presentaciones plenarias, numerosas discusiones van en twitter, en las comunidades de Slack, así como en reddit (ver, por ejemplo,
1 ,
2 ).
Esa es la pregunta!Todo esto es muy interesante e informativo para los especialistas que ya trabajan en el ecosistema Scala. Sin embargo, gran parte de la controversia está relacionada con varios defectos intuitivamente perceptibles o reales de Scala como lenguaje. Estos momentos pueden asustar a las personas "desde afuera", haciendo que pregunten: "¿Por qué debería usar Scala?", "¿Qué pasa si esto es un callejón sin salida?", "¿Scala 3 repetirá el éxito de Python 3?" etc. Como en la mayoría de las discusiones, los puntos más débiles y emocionales están llamando la atención, y este debate no es una excepción.
Entonces, demos
un paso atrás : ¿por qué necesitarías Scala? ¿Cuáles son las razones técnicas y comerciales para trabajar con este idioma?
Área temática del proyectoPara empezar, el lenguaje Scala es especialmente bueno para ciertas materias (¡pero no para todos!). El activo más importante de Scala es su
flexibilidad para definir abstracciones . A su disposición, una serie de simples "ladrillos" para esto; a veces, definir una abstracción no es más difícil que usar una clase, métodos y expresiones lambda. A veces tiene que usar un parámetro implícito o un método de extensión; en casos raros, solo queda recurrir a comandos macro. Sin embargo,
hay opciones .
Por lo tanto, Scala es perfecto para usted si necesita
navegar en un área temática compleja . Por ejemplo, podemos hablar sobre programación distribuida o competitiva. La concurrencia es muy difícil, y Scala tiene una serie de bibliotecas que simplifican esta tarea al construir abstracciones. Hay dos enfoques principales para esto: basado en el actor, implementado usando
Akka , y en el espíritu de FP, presentado por
Monix /
cats-effect y
Scalaz /
ZIO (si desea leer más sobre la comparación de estas herramientas, escribí una
serie de artículos sobre este tema )
Sin embargo, por supuesto, podemos hablar sobre otras áreas temáticas. Las capacidades de Scala también nos permiten llevar el modelado de aplicaciones comerciales típicas al siguiente nivel. Pero en este caso estamos hablando de la complejidad de un orden diferente. En el caso de los sistemas distribuidos, nos enfrentamos a la complejidad técnica. Al programar la lógica de negocios en aplicaciones, ya estamos hablando de la complejidad del área temática como tal. Por ejemplo, el libro de Debasish Ghosh "
Modelo de dominio funcional y reactivo " explica cómo combinar DDD con programación funcional y reactiva.
Dificultad del lenguajeNota: cuando se habla de Scala, a todos les gusta enfatizar la amplitud de posibilidades de este lenguaje, enfatizando que precisamente por su versatilidad, este lenguaje es tan complejo. Esto no es del todo cierto.
Como se mencionó anteriormente, Scala tiene una serie de construcciones básicas a partir de las cuales se pueden construir abstracciones. Sin embargo, todos ellos se pueden
combinar entre sí, por lo que el lenguaje adquiere tal flexibilidad. La mayoría de los proyectos innovadores que puede encontrar se reducen a una u otra combinación de tipos de orden superior, parámetros implícitos y subtipos.
Por lo tanto, con un número relativamente pequeño de características básicas (el tamaño de la gramática de Scala es más simple que Kotlin, Java o Swift), lo que, a su vez, facilita el aprendizaje, las opciones de combinación son mucho más numerosas.
¿La opción es demasiado amplia? No lo creo El programador, como profesional competente y responsable, es más que capaz de elegir la mejor opción para resolver un problema específico. Para obtener más información, consulte el artículo "
Pila Scala simple ".
Java solo mejorAhora se habla mucho de que
Kotlin ha suplantado a Scala como "como Java, solo que mejor". Pero creo que
es Scala, y no Kotlin , quien aún merece ese título. Hay dos razones principales para esto:
Primero, la
inmutabilidad en Scala es primordial . Esto se debe a la naturaleza de Scala como tal: escribir código en él es conveniente principalmente con la ayuda de datos inmutables. Dichos datos incluyen, en particular:
val
(como unidades de la primera clase), clases de
case
, funciones de orden superior, etc. Pero el punto es cómo se diseña y se escribe la biblioteca de idiomas estándar de Scala; Todas las estructuras de datos utilizadas por defecto son inmutables. Gracias a la inmutabilidad, se simplifican varias cosas, especialmente en nuestro mundo de alta competencia, donde esos idiomas ganan, donde se prefiere la inmutabilidad.
En segundo lugar, Scala admite
constructores de tipos, tipos de orden superior y tipos de clase (declarados implícitamente), lo que simplifica enormemente el trabajo con tipos de envoltura / contenedor, por ejemplo,
Promise
,
Future
o
Task
. Tales envoltorios prevalecen cuando se programa en un estilo asíncrono o reactivo, y la presencia de construcciones de lenguaje que simplifican el trabajo, digamos, con una base de código donde
Future
se usa activamente es otro argumento a favor de Scala.
¿Qué son los tipos de clase? Su función es aproximadamente la misma que la de los patrones de diseño en Java, sin embargo, son más flexibles y fáciles de usar en cuanto entiendes su significado. Hay algunas guías excelentes sobre esto, como
1 ,
2 .
¿Qué pasa con los constructores de tipos? Estos son tipos como
Future
u
Option
, que sirven como "contenedores" o "envoltorios" para otros tipos. Por lo tanto, puede tener la
Option[String]
o
Future[Int]
. Los tipos de orden superior le permiten escribir código que abstraiga cualquier contenedor. Ver por ejemplo.
1 ,
2 .
De repente te preguntas, ¿por qué incluso recurrir a
Future
/
Task
? El punto no es solo que la mayoría de los cálculos "reactivos" de alto rendimiento con demoras mínimas se realizan utilizando E / S asíncronas, para lo cual simplemente se solicitan tales diseños. Se dan otras razones en esta
discusión sobre reddit y en mi artículo “
¿Por qué molestarse con los envoltorios? "
Trabajar en un entorno predominantemente sin cambios, así como la capacidad de manejar convenientemente construcciones como
Future
,
Promise
o
Task
(¡y abstraerlas!) Transforma radicalmente su código. A primera vista, esto puede no ser obvio: si tiene experiencia Java o Ruby detrás de usted, entonces no podrá darse cuenta de estos aspectos de Scala de inmediato. Pero, incluso desde un punto de vista educativo, es útil comprender cómo funciona el enfoque "funcional" y, lo que es más importante, por qué puede llegar a ser una
alternativa muy valiosa .
Naturalmente, tanto Scala como Kotlin tienen una serie de ventajas comunes sobre Java, por ejemplo:
- Sintaxis más compacta
- Código menos estereotipado
- Un sistema de tipo más rico
- Falta de lastre de lenguaje
Al mismo tiempo, ambos idiomas proporcionan acceso al ecosistema de bibliotecas y marcos JVM.
Cuanto más rico es el sistema de tipos (en Scala es más rico que en Kotlin, y en Kotlin, más rico que en Java), el compilador realiza más trabajos de verificación y no la persona. Para esto se crearon las computadoras: para realizar tareas repetitivas aburridas y rutinarias. Verificar la aplicabilidad de los tipos es definitivamente una de estas tareas.
Al mismo tiempo, un sistema de tipo rico es útil no solo al
escribir código , sino también, en mayor medida, al
leer código . Cuando es fácil para usted navegar por la base del código, comprender lo que está haciendo y, además, no da miedo (o no da tanto miedo) emprender su
refactorización , esto caracteriza el lenguaje de manera muy positiva tanto desde un punto de vista técnico como aplicado.
FP vs OOPOtra pregunta que a menudo surge en tales discusiones es si el lenguaje Scala debe seguir adhiriéndose a la síntesis de OOP y FP, o si debe desarrollarse a lo largo de un camino puramente funcional. Soy
partidario de la síntesis , especialmente porque FP y OOP, en mi opinión, no son enfoques alternativos, sino que se complementan entre sí.
FP está
programando usando funciones , aunque no ninguna, pero referencialmente transparente (vea esta
respuesta a reddit en un hilo anterior, donde la transparencia referencial se explica perfectamente). En OOP, la comunicación con los objetos se organiza mediante "mensajes" o, en nuestra terminología, llamadas a métodos virtuales. ¡No hay una sola razón por la que estos dos enfoques no puedan coexistir, y Scala ya lo ha demostrado!
En un
tweet sobre las virtudes de Scala, John de Goes menciona algunas características de OOP que son útiles en un enfoque puramente funcional, en particular,
módulos de primera clase (obtenidos al componer objetos),
sintaxis de puntos (métodos de llamada en objetos) e
instancias de clases / tipos como construcciones de primera clase . Todos estos son elementos de una combinación exitosa de dos paradigmas. Tal vez algunos más están a la vuelta de la esquina?
El proyecto de "síntesis" aún no se ha completado, definitivamente hay un campo de discusión aquí. Un aspecto incompleto es la sintaxis propuesta para los métodos de extensión, que debería reemplazar las conversiones implícitas mucho más confusas. Otro es optimizar la sintaxis de las clases de tipos;
La sugerencia hecha hace un tiempo es claramente cruda y no cubre algunos de los usos más comunes de las mónadas en Scala. Algunas sugerencias son mejores, otras requieren refinamiento, pero es bueno que se reciban y se estén discutiendo sobre ellas; Gracias a ellos, el idioma vive y, en última instancia, la mejor solución está fijada en él.
Scala 3Scala 3 se lanzará en dos años. Aparecerán varias posibilidades interesantes, en particular, tipos opacos, parámetros de rasgos, un nuevo enfoque de metaprogramación, tipos de unión e intersección, tipos de funciones implícitas: estos son solo algunos ejemplos. Por supuesto, existe una preocupación (bien fundada) sobre la migración.
Ya se sabe que se introducirá una herramienta especial para
la migración automática de código de Scala 2 a Scala 3 usando
scalafix . Dado que Scala es un lenguaje de tipo estático, dicha tarea se puede resolver a gran escala y es mucho más simple que, por ejemplo, en Python. Pero, por supuesto, no hay magia aquí: incluso si esta herramienta proporciona una cobertura correcta del código del 99%, el 1% de los casos más problemáticos aún permanecerá. Como no puede contar con la magia, la migración de estos fragmentos deberá realizarse manualmente.
Estos son los costos de trabajar con un lenguaje en desarrollo activo: obtienes las últimas oportunidades, pero algunas de ellas no son tan buenas y deben mejorarse. Aun así, los cambios propuestos no son revolucionarios. El lenguaje Scala 3 es muy similar al Scala 2, no se esperan grandes cambios de paradigma.
Es alentador que el equipo de Scala se tome en serio la migración. Mientras que la migración anterior entre versiones anteriores de Scala (por ejemplo, de 2.8 a 2.9) era bastante onerosa, las migraciones recientes fueron mucho mejores. Hay tres partes principales involucradas: EPFL,
ScalaCenter y
Lightbend, todas (a menudo juntas) trabajan para facilitar la migración. Por ejemplo, existe una herramienta
MIMA compatible con binarios, y constantemente se crean numerosas bibliotecas nuevas en la comunidad para garantizar un trabajo conveniente con nuevas versiones de Scala.
Finalmente, la herramienta TASTY aún sin terminar (que, en consecuencia, aún no se puede evaluar) debe garantizar el uso de archivos binarios de Scala 2 a Scala 3.
Entonces, ¿por qué usar Scala?Entonces, ¿cuáles son las razones para detenerse en Scala, si considera este lenguaje desde un punto de vista comercial? Todas las ventajas técnicas anteriores son directamente útiles para las empresas. Cuando tiene un idioma en el que puede escribir código complejo con menos errores, se le proporciona un retraso mínimo en términos y usuarios satisfechos. Si comienza a escribir aplicaciones competitivas potentes y prácticamente antideslizantes para Scala, para las cuales se proporcionan herramientas especiales en Scala, esto resultará en un gran beneficio para su empresa.
Además, no se olvide de
Spark , la plataforma líder para
el análisis de datos distribuidos . Scala se utiliza no solo para implementar Spark como tal, sino también para definir los cálculos en sí. Aquí hay otra abstracción orientada a la ciencia de datos que oculta un modelo computacional complejo.
ResumenPor supuesto, hay problemas en Scala, pero ¿dónde no están? La razón del optimismo es que muchas personas que usan Scala a diario están trabajando activamente para
mejorar las herramientas , las bibliotecas y el lenguaje en sí. Puedo suponer que continúan trabajando con Scala precisamente porque, con todas las deficiencias disponibles, ni un solo idioma es tan adecuado para su área temática.
Scala le permite desarrollar su propio estilo de programación, sin importar el lenguaje que solía ser: Java, Ruby, o simplemente probarlo en la programación. No hay un enfoque excepcionalmente ganador para Scala; ya sea el enfoque más
imperativo de Akka, o el enfoque más
funcional de Cats y Scalaz.
Aquí es donde se puede ver el problema: hay fracciones en la comunidad de Scala que se adhieren al enfoque "reactivo", "sintético" OOP / AF y AF puro. Sin embargo, de hecho, esta es una gran ventaja. Debido a tal diversidad, se están llevando a cabo discusiones, se expresan muchas opiniones diferentes desde diferentes puntos de vista. En esto, a su vez, puede aprender perfectamente cómo resolver problemas no estándar y enriquecer sus propias herramientas.
Cualquiera sea el camino que elija en Scala, contará con el apoyo de una impresionante comunidad de colegas involucrados en el desarrollo de bibliotecas y marcos; Estas personas siempre están listas para ayudar y discutir ideas emergentes.