Cuando alguien mira el código Corda , inmediatamente se da cuenta de que está escrito en Kotlin, el nuevo lenguaje de programación de JetBrains, que se puede compilar para JVM y Javascript. Fue una elección inusual, y en este artículo quiero compartir algunas razones para esta decisión y la experiencia de nuestro "año con Kotlin en producción".
¿Por qué Kotlin?
Esta solución se puede dividir en dos partes:
- ¿Qué plataforma usar? ¿JVM, .NET, Node, Python / Ruby, Go, Haskell o algo compilado (en código máquina)?
- ¿Qué idioma usar si elige JVM? Java? Si no, ¿por qué? Y si no, entonces qué más: Scala, Ceilán, Clojure, Kotlin, Python, Ruby, Javascript o Haskell (porque todos tienen una implementación para JVM).
Las razones para elegir JVM como plataforma son bien conocidas en el entorno de aplicaciones empresariales, y no tiene mucho sentido detenerse en esto. Baste decir que si necesita un tiempo de ejecución multiplataforma escalable, seguro para subprocesos con recolección de basura , y con muchas bibliotecas bien documentadas que resuelven problemas comerciales básicos, entonces la elección se reduce solo a JVM y .NET.
Al comienzo del trabajo en Corda, el proyecto no tenía nombre y era difícil imaginar que en el futuro se convertiría en un producto. De hecho, cuando el proyecto que se convirtió en Corda comenzó en diciembre de 2015 (en mi primer día de trabajo), no había ningún plan para crear un nuevo sistema corporativo de contabilidad distribuida. Corda comenzó como un conjunto de prototipos para explorar nuevas ideas y requisitos en los que estaba interesado el Grupo de Trabajo de Arquitectura del Consorcio, especialmente aquellos relacionados con la visibilidad limitada de los datos y el modelo de datos que proporciona la escalabilidad del "conjunto UTXO de matrices de salida transaccional" junto con la programabilidad de los imperativos contratos inteligentes de Ethereum en general.
Debido al hecho de que no estaba claro si estos prototipos se convertirían en algo, o simplemente servirían como información para otros productos en el mercado, enfrentamos una decisión difícil. Por un lado, queríamos explorar de manera rápida y productiva algoritmos y estructuras de datos. Por otro lado, debería haber una oportunidad potencial para crear un gran producto corporativo y contratar rápidamente personas para ello.
Java definitivamente cumplió con estos requisitos, pero la falta de características modernas en el lenguaje reduce significativamente la productividad y, más implícitamente, la moral de los desarrolladores.
No se consideró la tipificación dinámica: los beneficios de la corrección, las herramientas de desarrollo y el rendimiento proporcionados por la tipificación estática son demasiado grandes para ser descuidados.
Los idiomas fundamentalmente diferentes de los más populares tampoco se consideraron, porque Queríamos poder contratar expertos financieros. Y, aunque es completamente posible crear un equipo en torno a un idioma como Haskell, encontrar una persona con experiencia bancaria seria e idiomas perezosos (perezosos) puros (funcionales) que viven al azar en Londres parecía riesgoso. Además, la naturaleza misma del producto implica que nuestros "usuarios" son en realidad desarrolladores de complementos y aplicaciones que usan la plataforma, y no tiene sentido exigirles que aprendan paradigmas y herramientas completamente nuevos. Nuestra elección del idioma no debería limitar demasiado a los usuarios.
Como resultado, estos requisitos nos dejaron con Kotlin, Scala y Ceilán. Estos lenguajes son bastante similares e interesantes. Elegimos Kotlin por las siguientes razones:
- Integración casi perfecta con Java
- En particular, los programas de Kotlin utilizan una versión mejorada (compilada) de las colecciones JDK estándar, lo que garantiza que no haya problemas de integración debido al uso de otras bibliotecas de colecciones. Transmitimos y recibimos colecciones hacia y desde las bibliotecas de Java en todas partes, por lo que es importante que esto no cause problemas.
- De las clases de Kotlin, obtenemos una API Java simple con los métodos
get
/ set
/ is
de acuerdo con los tipos. No se requieren anotaciones especiales u otras acciones para esto. Por la razón de que Corda proporciona una API diseñada para un uso transparente por los desarrolladores de Java, esta es una gran ventaja: del código ordinario, obtienes una API que no se puede distinguir de la API de Java con solo algunas advertencias (por ejemplo, la interceptación explícita de las excepciones comprobadas de Java requiere explícita método de anotación)
- El compilador realiza funciones pequeñas en línea como
map
/ filter
/ fold
/ groupBy
(en lugar de esperar que la JVM lo haga por sí mismo). Desafortunadamente, el compilador JIT JVM, aunque excelente en general, no elimina en todos los casos la sobrecarga del uso abundante de funciones de orden superior. El uso de Kotlin compensa esto, además de permitirle controlar la ejecución del programa desde las funciones lambda (nota: por ejemplo, retorno no local ). Esta es una de las características poco conocidas, pero al mismo tiempo útiles. Porque en todos los lugares donde escribimos código con un estilo tan funcional, si se traduce mal en código de máquina, podríamos crear problemas de rendimiento para nosotros mismos. - Debido al hecho de que el código en Kotlin se traduce en un código Java bastante similar, casi todas las herramientas orientadas a Java existentes funcionan de forma inmediata . Esto no siempre es cierto en el caso de otros idiomas. Por ejemplo, Quasar tiene dificultades para instrumentar el código Scala porque necesita anotaciones de método, y Scala traduce lambdas en métodos que no pueden ser anotados. Las lambdas de Kotlin generalmente están incrustadas (ver arriba), o pueden ser anotadas de otra manera.
- La excelente documentación y una pequeña biblioteca estándar hacen que el aprendizaje sea muy rápido. No indicamos en nuestras vacantes la necesidad de experiencia en Kotlin, y contratamos personas sin su conocimiento dando 1-3 años después de lo cual un nuevo miembro del equipo pudo escribir código idiomático.
- Según la selección de candidatos que nos entrevistaron, IntelliJ es el IDE más popular (tenían una libre elección de herramientas). Entre los lenguajes posteriores a Java, IntelliJ admite lo mejor de Kotlin.
- Ya tenía una experiencia satisfactoria con él y, por lo tanto, estaba seguro de que a sus nuevos colegas también les gustaría.
Si no fuera por Kotlin, probablemente elegimos Scala: Kotlin está inspirado en gran medida por él y ambos son buenos idiomas.
Nuestro año con Kotlin
¿Cómo es un año para trabajar con un nuevo idioma en el contexto de una aplicación corporativa?
Lo más importante fue, sin lugar a dudas, escuchar de colegas que realmente les gusta trabajar con él. El lenguaje de programación es un asunto personal para todos, y las personas generalmente tienen una opinión definitiva sobre este asunto. Si, como la primera tarea en un nuevo trabajo, le pide a alguien que aprenda un nuevo idioma y ni siquiera lo advierta con anticipación, entonces siempre existe el riesgo de que un colega simplemente lo odie y lo encuentre molesto en lugar de aumentar su productividad. Pero este no es el caso.
Los siguientes son algunos de los problemas que a menudo surgen en un entorno de desarrollo empresarial posterior a Java / C # que nosotros mismos hemos encontrado:
- El código se ve diferente dependiendo de quién lo escribió. En general, no es un gran problema. A diferencia de Go, que requiere un cierto estilo de diseño, el código de Kotlin de diferentes autores puede verse diferente. Pero IntelliJ tiene una herramienta de formato que proporciona un estilo base de código unificado. Es más limitado que para Java, pero eso es suficiente. Un problema más sutil, especialmente con el código Scala, es la oposición del estilo de codificación Java-OOP y Haskell-FI. El código Scala que usa bibliotecas como scalaz puede ser difícil de leer para los desarrolladores que esperan ver Java mejorado . En este debate, Kotlin está muy firmemente del lado de Java mejorado . Y, aunque la programación funcional, de cierta manera, posiblemente en Kotlin, la comunidad (al menos por ahora) no se ha dividido en campamentos. Tuvimos casos en los que el código se escribió como si fuera Haskell, pero se resolvió en codereview.
- Bibliotecas En Corda utilizamos más de 50 bibliotecas de código abierto y no hubo problemas con ninguna. Nunca escribimos envoltorios o capas de adaptadores. Como los sistemas de compilación en proyectos en Kotlin, Maven o Gradle se usan generalmente, no hay un reemplazo oficial específico de Kotlin para estas herramientas (¡aunque Gradle ha introducido el soporte de Kotlin como un nuevo lenguaje de secuencias de comandos!).
- DSL y SQL. C # tiene LINQ, Java tiene JOOQ y Kotlin ha expuesto . Esta es una de las áreas donde Kotlin es algo más débil que sus competidores: Exposed es un gran ejemplo del uso de las capacidades de Kotlin para construir DSL, pero la biblioteca en sí tiene una API inestable y es un proyecto secundario. JOOQ, por supuesto, se puede usar con Kotlin y, mirando hacia atrás, esta parece ser la opción preferida.
- IDE / kit de herramientas. El complemento de Kotlin para IntelliJ está, por supuesto, escrito por JetBrains y, en general, es excelente. Sin embargo, es menos sofisticado en comparación con el soporte de Java. Las nuevas funciones del editor, como una sugerencia de parámetro , se deben portar manualmente a Kotlin, y el soporte en sí mismo, como tal, generalmente va a la zaga de los complementos Java mucho más antiguos. También notamos que el complemento IDE a menudo notifica errores internos, aunque la frecuencia de las excepciones IDE ha disminuido significativamente durante el año (y parece que no afectan nada). Usar otras herramientas tampoco causa problemas, porque lo que está escrito para Java generalmente funciona de forma predeterminada . Una excepción son las herramientas que funcionan con código fuente en lugar de bytecode y que, obviamente, no se pueden reutilizar. Con todo esto, el compilador Kotlin y el complemento IDE no están tan depurados como en el caso de Java, incluso un año después del lanzamiento de 1.0. Lo más probable es que nunca encuentre errores internos en
javac
, pero, aunque muy raramente, todavía los vemos en Kotlin. - Reconocimiento por parte de los usuarios. Los usuarios de Corda suelen ser instituciones financieras grandes y conservadoras. Dichas empresas prefieren usar lenguajes comunes y bien establecidos. Kotlin, al no ser ni lo uno ni lo otro, claramente causó cierta sorpresa en el momento en que comenzamos. "¿Por qué Kotlin?" - Esta es una pregunta que, durante el año pasado, prácticamente ha desaparecido, porque la gente miró más de cerca y se dio cuenta de que esto no es tan arriesgado como suele ser el caso con los nuevos lenguajes de programación. También intentamos facilitar la adopción al proporcionar ejemplos de código que demuestran que la creación de aplicaciones utilizando la plataforma no requiere el conocimiento de Kotlin. Los resultados de esto no fueron tan exitosos: muchos desarrolladores que trabajan por primera vez con Corda todavía comienzan explorando Kotlin. No está muy claro si este es el resultado del hecho de que hayamos proporcionado ejemplos y documentación de uso insuficientemente orientados a Java, o si es solo una buena excusa para aprender una nueva herramienta interesante. También nos ayudó la creciente adopción de Kotlin dentro de los principales bancos de inversión. Durante el año pasado, hemos escuchado de varios miembros del consorcio que sus equipos de desarrollo interno han comenzado a buscar seriamente en Kotlin sus propios productos: a menudo impulsados por la disponibilidad de herramientas que convierten Java a Kotlin, que proporcionan una integración significativamente menos dolorosa en la base de código existente.
- Soporte comercial. El riesgo de usar lenguajes poco conocidos es que pueden dejar de desarrollarse o tener objetivos que no son consistentes con las necesidades formadas en torno al producto, la comunidad de usuarios (por ejemplo, en el caso de los lenguajes de investigación, el objetivo principal de los desarrolladores es crear artículos científicos). La razón principal por la que nos sentimos confiados con Kotlin es que JetBrains es una compañía estable y rentable que ha estado en el mercado por más de 15 años. JetBrains rápidamente comenzó a probar su propia herramienta al introducir a Kotlin en el código de los principales productos. Por lo tanto, el riesgo de terminación del soporte es bastante pequeño. Además, JetBrains ya es una empresa de mediana edad, y su mercado objetivo (IDE y herramientas de desarrollo) ha dejado de ser nuevo o especialmente de moda, lo que reduce el riesgo de una posible adquisición de la empresa, lo que puede conducir a cambios estratégicos impredecibles. Y, a pesar de la falta de un paquete de soporte comercial para Kotlin, en la práctica el equipo soluciona rápidamente los problemas conocidos. Por el momento, JetBrains tiene la intención de lanzar la próxima actualización de idioma después de un año desde la versión 1.0. Este ciclo de lanzamiento es bastante similar al ciclo de desarrollo en el entorno corporativo.
Conclusiones?
No nos arrepentimos: la elección de un idioma joven al comienzo de este proyecto fue, aunque un riesgo, pero equilibrado. Hizo un buen trabajo para nosotros y no cambiaríamos nuestra elección.