2. Introducción

Origen

En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un programador de los de Lisp en astillero. Es, pues, de saber, que este sobredicho hidalgo, los ratos que estaba ocioso desarrolló dotLisp, un proyecto muy parecido a Clojure pero basado en el ecosistema de .NET. Se hacía llamar Rich Hickey. Después se dio a leer libros de funcional con tanta afición y gusto, que olvidó casi los objetos. Con éxito desarrolló otros 3 proyectos donde consiguió herramientas de interoperabilidad entre Lisp y Java.

Con todo lo aprendido decidió empezar un proyecto nuevo, un lenguaje de programación que modernizara Lisp y trabajara muy estrechamente con la máquina virtual de Java. Sin ningún anuncio público, trabajó durante 2 años y medio en su primera versión de Clojure. Sin ayudas económicas, y en algunos periodos dedicando su tiempo completo.

Durante todo el proceso fue publicando en su blog los avances hasta que un día, el 16 de octubre de 2007, envió emails a algunos amigos de la comunidad Common Lisp anunciando la versión estable. Su implementación gustó tanto que se empezó a utilizar como un dialecto contemporáneo de Lisp, y parte de la comunidad fue incorporándose de forma gradual pero imparable.

Paradigma

Los lenguajes de programación se podrían clasificar en 3 grandes paradigmas: los imperativos (C, COBOL…) que acentúan los cambios en las variables, los orientados a objetos (C++, Java, PHP, Python, JavaScript…) evolución de los imperativos cuya fuerza radica en el empaquetamiento, y los funcionales (Lisp, Haskell, Scala, Elm…) donde se usan expresiones con entradas y salidas. Ninguno es superior a otro, son diferentes puntos de vista para resolver los mismos problemas. En este caso Clojure estaría dentro de los puramente funcionales, un lenguaje excepcional por disponer las mejores herramientas del paradigma con el rendimiento de Java al usar su máquina virtual (aunque existen otras implementaciones). Y a la vez es maravilloso ya que puede invocar todo el ecosistema escrito en Java durante casi 3 décadas.

¿Cómo se pronuncia?

Antes de continuar profundizando debemos aclarar que Clojure se pronuncia como en inglés Closure (/ˈkloʊʒər/). Su nombre es un juego de palabras: "C" de C#, "L" de Lisp y "J" de Java. Los lenguajes que influenciaron a su creador, Rich Hickey (creador del lenguaje), en su diseño [^1]. Una elegante forma de agradecer a todos los que trabajan detrás de esos lenguajes permitiendo que Clojure sea real.

Implementaciones

Como en la gran mayoría de lenguajes Lisp, Clojure antes de ser ejecutado su sintaxis debe ser parseada y construida sobre expresiones en árbol (S-expressions). Esta característica tan particular abre la puerta a que sea posible construir diferentes implementaciones independientemente del compilador. Se separa la sintaxis y sus expresiones del motor que será el encargado de compilarlo. Entre ellas tenemos:

  • Clojure: usando la máquina virtual de Java, la implementación principal. Combina código Java y Clojure.

  • ClojureCLR: nativamente implementado en Common Language Runtime (CLR), el motor de ejecución del .NET Framework de Microsoft. Gran parte está en C#.

  • ClojureScript: compilador de Clojure para JavaScript. Genera código JavaScript compatible gracias al optimizador de Google Closure. Los frameworks más populares hacen uso de React (re-frame, Reagent…).

  • Babashka: intérprete nativo para scripting, puede utilizarse como una alternativa a la hora de realizar scripts de Bash.

Existen muchas otras no oficiales, pero ninguna posee el apoyo tan grande de la comunidad y el mantenimiento de las actualizaciones.

No es un caso único ya que podemos encontrar otros lenguajes como puede ser Python: CPython (oficial sobre C), Jython (Java), IronPython (.NET), etc. Lo realmente potente y diferenciador son los llamados Macros, que te permiten colarte en el árbol de expresiones antes de ser lanzado permitiéndote… si estás de pie busca una silla… ¡crear tu propio lenguaje de programación dinámicamente! Cuando lleguemos al capítulo reservado al tema comprenderás su significado y relevancia.

Empresas que lo utilizan

Diferentes firmas e instituciones gubernamentales lo usan principalmente para todo lo relacionado con desarrollo web (APIs y microservicios), IA (siempre ha destacado Lisp en este área) y desarrollos de gran rendimiento. Nos podemos encontrar:

  • Apple.

  • Atlassian (empresa detrás de Bitbucket, Jira, Trello…).

  • Netflix.

  • Walmart.

  • Base2 (aviones Boeing).

  • NASA.

  • Nubank.

Aunque también es usado para la industria de la música, videojuegos, IA y… ¡poesía [^2]!

Ventajas y desventajas

Pros

  • Toda la solidez de los lenguajes funcionales. Las variables son inmutables lo cual quita de cuajo gran parte de errores que te puedes encontrar en cualquier otro lenguaje.

  • Desacoplado del compilador. Puede funcionar sobre otros lenguajes como C#, JavaScript y otros no oficiales. Sin olvidar al poderoso Java cuyo rendimiento sería similar a programar entre C++ y Go [^3].

  • Secuencias perezosas, posibilidad de trabajar con datos que no son calculados hasta que quieras averiguar su valor. Esto hace que su rendimiento se dispare.

  • Paralelismo. Realmente sencillo y totalmente nativo el uso de varios hilos de ejecución.

  • Fácil de empaquetar y desplegar, como en un jar.

  • Macros, crea tus propias estructuras del lenguaje si no existen.

  • Posibilidad de trabajar tanto para el escritorio como desarrollo web (Back-End y Front-End).

Contras

  • Pocas similitudes con la programación orientada a objetos, necesitarás un esfuerzo de comprensión y persuadir a tus compañeros para integrarlo.

  • En tu equipo deberás instalar Java, C# o JavaScript para ejecutarlo.

  • Si no creas un ejecutable nativo, o lanzas tu código directamente con Java, será lento al inicio.

Sintaxis

Vamos a empezar a familiarizarnos con la sintaxis. Todo el lenguaje se basa en funciones, lo cual significa que siempre vamos a utilizar funciones para todo, incluyendo declarar variables.

Función

Si ya conoces algún dialecto de Lisp no tendrás problemas, es prácticamente igual. En caso contrario te comento que el orden siempre será el mismo: nombre de la función y argumentos, delimitado por paréntesis.

En el ejemplo se declara una variable y restamos su cantidad. Los comentarios empiezan con ;.

; Soy un comentario
; Defines una variable llamada `edad`
(def edad 42)

; Usamos la función llamada `-` para restar
(- edad 8)

; Devuelve => 34. Nos hemos quitado 8 años de un golpe

Los argumentos pueden ser variables u otras funciones, que a su vez tendrán su nombre y otras variables.

Funciones dentro de funciones

En el siguiente ejemplo buscamos obtener los números pares del 0 al 10. Para ello usaremos la función even? que nos dirá si el argumento es par, range otra función que nos devuelve un rango de 10 números y filter que nos filtrará el contenido por medio de even?.

(filter even? (range 11))
; Devuelve => (0 2 4 6 8 10)

; (filter [función] [listado]) -> función de filtrado
; even? -> función que comprueba si un número es par
; (range 11) -> función que devuelve un listado de 11 números (0 1 2 3 4 5 6 7 8 9 10)

No aspiro a que entiendas qué ha pasado, sino que empieces a encontrar un patrón de comportamiento. El orden de las funciones, o el contenido de los paréntesis, son importantes para determinar quién se ejecuta antes que otro. Como en las matemáticas, se ejecutan primero los paréntesis más pequeños y paulatinamente los siguientes más grandes.

Con el tiempo acabarás escribiendo en una línea elegante, sencilla y eficiente.

Resumen

  • La programación funcional es uno de los 3 paradigmas.

  • Clojure es un dialecto de Lisp.

  • Existen diferentes implementaciones, aunque la realizada en Java es la más popular.

  • Todo son funciones que siempre devuelven un valor u otra función.

Ejercicios

  1. Busca en internet cuándo apareció Lisp.

  2. Encuentra un gráfico de S-expressions e intenta imaginar cómo sería la siguiente operación: 2 x (3 + 4).

  3. En YouTube, visualiza alguna charla de Rich Hickey.

Nota: al final del libro podrás encontrar las soluciones.

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Will you buy me a coffee?

Visitors in real time

You are alone: 🐱