Empezando a jugar con Clojure

Matías Mascazzini
Memorias de un Techie
9 min readMay 15, 2016

--

Dicen que cuando estas aprendiendo algo nuevo lo mejor para fijar los conceptos es tratar de explicarle a otro. Y la mejor forma de enseñarle a otro es cuando aun recuerdas lo difícil que fue cuando no sabias nada.

Así que estos textos son un experimento de ello y por lo tanto debes tomarlos con pinzas y su precisión esta en duda desde el primer párrafo. No pretende ser una guía de enseñanza sino un recordatorio personal y una fuente de recursos para iniciarse en este viaje.

¿Que es Clojure?

Clojure (en adelante CLJ) es un lenguaje de programación funcional, un dialecto de LISP, que corre sobre la maquina virtual de JAVA, de .Net ( ClojureCLR) y puede ser compilado a JavaScript (ClojureScript), así que parece compatible con grandes corpos; ellos se definen como “robust, practical, and fast” su objetivo es simplificar la concurrencia, esto último es lo que lo hace ser muy interesante.

El correr sobre JVM (maquina virtual de JAVA) hace que la llamada a librerías de JAVA se muy sencilla lo cual lo hace más poderoso.

Por ahí leí que CLJ se destaca por ser “efficient, immutable data structures, optional lazy evaluation, protocols and records/structs.”

Más sobre ̶L̶I̶S̶P̶ ̶̶ Clojure en Wikipedia https://es.wikipedia.org/wiki/Clojure o en http://clojure.org/. O un artículo, en ingles, bien completo en Clojure — Functional Programming for the JVM. Y la Wiki de ellos mismos.

¿Por qué CLJ?

http://clojure.org/about/rationale

¿Con que se ̶c̶o̶m̶e̶ corre?

Para probar ya mismo! podes entrar a este sitio web http://www.tryclj.com/ (código fuente) y jugar un poco.

Al ser algo compilado necesitas compilarlo primero. Pero se usa algo llamado REPL (Read-Eval-Print Loop) como para ir evaluando el resultado de las funciones. Así que de alguna manera hay que instalar ese REPL.

CLJ necesita Java 1.6 o superior y el archivo .JAR de Clojure en si mismo. Entonces te lo bajas de Download y lo descromprimis, te vas a una consola y ubicado en esa carpeta, ejecutas:

java -cp clojure-1.8.0.jar clojure.main

Y para compilar un archivo especifico:

java -cp clojure-1.8.0.jar clojure.main nombreArchivoACompliar.clj

Para manejar los proyecto (y sus dependencias) se usa algo llamado Leiningen http://leiningen.org/ que trae ese REPL.

Instalando Leiningen en Linux Mint.

$ mkdir ~/bin
$ wget https://raw.github.com/technomancy/leiningen/stable/bin/lein -P ~/bin/
$ chmod a+x ~/bin/lein
$ export PATH=$PATH:/home/<your username here>/bin

Entonces con Leiningen instalado, podemos ejecutar:

lein repl

y empezar a jugar con CLJ.

Mejor documentado en el sitio oficial http://clojure.org/guides/getting_started

Editor de Código.

Pero para empezar a codear en casa, podemos usar un editor de código de código abierto y gratuito llamado Ligth Table que tiene versiones para Windows, Mac y Linux de 64bit. Y tiene la facilidad ejecutar el código de CLJ de una forma muy interesante. Otro editor es Nightcode https://sekao.net/nightcode/

LigthTable.

Una vez instalado LigthTable, lo ejecutamos y dentro de él creamos un archivo con extensión “.clj”. Entonces para probar el código de CLJ nos paramos en la linea y presionamos CTRL+ENTER. Por ejemplo:

(ns holamundoclojure)
((fn [] "Hola Mundo!" )) ; presiona CTRL+ENTER aquí

deberías ver “Hola Mundo!”, iluminado, como en la imagen a continuación

SublimeText

Probé con SublimeText, se puede pero es un poco más complicado al principio. Tenes que instalar una serie de plugins: paredit, lispindent, y SublimeREPL.

Luego levantar el REPL, desde /Tools y una vez que lo tenes corriendo en una ventana, podes compilar y evaluar tu código clojure. OJO! Tenes que presionar la combinación CTRL + , (tecla coma), soltar y luego presionar solamente la acción que queres y ves los resultados en la otra ventana, para eso te recomiendo partir en 2 desde /View/Layout/Rows: 2 o Shift+Alt+8

 ctrl+ , release s = Selection
ctrl+ , release f = File
ctrl+ , release l = Lines
ctrl+ , release b = Block

Notación Polaca?

La forma de escribir las fusiones en Clojure es con Notación Polaca (Polish notation) donde el operador esta a la izquierda de sus operandos.

(operador operando operando operando)

(+ 1 1 1) ; salida => 3

Por lo que entendí en CLJ todo se ejecuta en unas “Form” que son las que va leyendo el interprete para compilar. Y estas asumen que son una función con sus argumentos. Y siempre estarán encerradas por 2 paréntesis (). [Bienvenido al mundo de los paréntesis, más vale que te ordenes]

Todo empieza declarando un “namespace”. Y con “;” definimos los comentarios.

(ns miapp)
; imprime un mensaje en la consola
(print "Hello World of Clojure")
; las operaciones, siguiendo la notación polaca.
(+ 1 1)
(- 2 1)
(* 4 2)
(/ 4 2)
; combinando operaciones, con prioridad de adentro hacia afuera.
(* 3 (- 5 1))

Pasa saber de que tipo de datos son las variables, podemos usar 2 formas.

; saber que tipo de dato es o a que clase pertenece
(type 1)
(class 1)

Las funciones.

; Usa fn para crear nuevas funciones. Una función siempre devuelve
; su última expresión
(fn [] "Hola Mundo!") ; salida => fn

; (Necesitas rodearlo con paréntesis para invocarla)
((fn [] "Hola Mundo!")) ; salida => "Hola Mundo!"
; Para definir una variable usamos def, aquí asignamos la función a una variable para que sea más fácil de usar.
(def saludar (fn [] "Hola"))
(saludar) ; salida => "Hola";Una forma más corta de hacer lo anterior
(defn saludar2 [] "Hola mundo!")
(saludar2) ; salida => "Hola mundo!"; Parece como una función sin nombre.
(def Salute #(str "Hola"))
(Salute) ; salida => "Hola"

Funciones con Argumentos.

La lista de argumentos en una fusión es un vector separado por espacios, luego viene lo que devuelve la función, en el ejemplo es una cadena STR.

(ns jugandoconclojure)(defn NombreYApellido [nombre apellido] 
(str "Bienvenido, " apellido " " nombre "."))
(NombreYApellido "Cosme" "Fulanito") ;salida=> "Bienvenido, Cosme Fulanito."

Funciones con muchos argumentos

; Funciones con muchos argumentos. [& args]
; se puede definir con args, o se pueden definir diferentes implementaciones para una misma función dependiendo de la cantidad de argumentos
(defn saludar
([] "Hola, Mundo!") ;sin argumentos
([nombre] (str "Hola, " nombre)) ; con 1 argumento
)
(saludar) ; salida => "Hola, Mundo!"
(saludar "Jose") ; salida => "Hola, Jose"
;Otro patrón en Clojure seria definir la función pero de forma re-cursiva.
(defn saludar
([] (saludar "Mundo!")) ;sin argumentos
([nombre] (str "Hola, " nombre)) ; con 1 argumento
)
(saludar) ; salida => "Hola, Mundo!"
(saludar "Jose") ; salida => "Hola, Jose"

; Las funciones pueden usar argumentos extras dentro de un secuencia utilizable en la función
(defn contar-args [& args]
(str "Usted paso "(count args) " args: " args))
(contar-args 1 2 3) ; salida => "Usted paso 3 args: (1 2 3)"
;Otra forma de función, es con parámetros como mapa o hash, valor clave.
(defn hola [{nombre :nombre}]
(str "Hola, " nombre))
(hola {:nombre "Cosme Fulanito"})

Colecciones de Datos.

Listas, vectores, mapas de hash {:clave valor},

Los mapas es uno de los conceptos más importantes para usar Clojure en la web.

Recursividad.

recur, optimiza el código.

Si hay algo que hace valioso a un lenguaje del paradigma funcional es la recursividad.

Conectando con JAVA.

(import …)

(Date.)

Librerias: Clojars.

Clojars. Las librerías se publican en un repositorio llamado Clojars, al mejor estilo RubyGems, allí puedes encontrar todas las disponibles https://clojars.org/

ToolBox. Y luego como El ToolBox de Ruby, hay un ToolBox de CLS, solo que no le dan una puntuación ni muestran la actividad de la libreria ni puntos de los usuarios. http://www.clojure-toolbox.com/

Leiningen.

Es un administrador de proyectos Clojure, esto incluye el manejo de dependencias y la realización de algunas tareas (al menor estilo make o rake), es el más usado pero existen otros como Boot (http://boot-clj.com/)

Los comandos/tareas del Leininge tienen la siguiente forma:

lein $TASK $TASK_ARGUMENTS

Para generar una app.

lein new [$TEMPLATE_NAME] $PROJECT_NAME

lein new luminus my-app

Para ejecutar la app, ingresar a la carpeta con el nombre de la app y ejecutar:

lein run

Una mejor referencia rápida a .CLJ

Además del TryCloujre.com, hay un excelente material de Adam Bard traducido al español, que da un vistazo rápido al lenguaje https://learnxinyminutes.com/docs/es-es/clojure-es/

También esta Clojure Script, que entiendo que es un compilador de Clojure a JavaScript. Se lo puede probar Himera que provee un ClojureScript REPL desde el navegador en http://himera.herokuapp.com/index.html

Cursos online.

Me costo encontrar un MOOC sobre Clojure, más bien encontraba sobre programación funcional, hasta que Nicolás Villalba me recomendó un Self-Paced MOOCs de la Helsinki Metropolia University… que dura una semana y esta basado en un repositorio de github.

http://iloveponies.github.io/

Jugar Clojure

una vez que le das una recorrida al lenguaje hay varias cosas con las que se puede jugar:

4Clojure.

Es un sitio que contiene una serie de problemas a ir resolviendo

Clojure Koans

Son los clásicos ejercicios Koan basados en pruebas unitarias que descargas y vas solucionando de a poco. http://clojurekoans.com/

Guía de Estilos.

Los lenguajes ya maduros suelen tener las "convenciones" o guias de estilo de como trabajar con ellos, esto nos sirve para entender el código de otros y viceversa.

Me encontré esta guía en GitHub, que tiene 2k+ de estrellitas….

The Clojure Style Guide

This Clojure style guide recommends best practices so that real-world Clojure programmers can write code that can be maintained by other real-world Clojure programmers. A style guide that reflects real-world usage gets used, and a style guide that holds to an ideal that has been rejected by the people it is supposed to help risks not getting used at all — no matter how good it is.

The guide is separated into several sections of related rules. I’ve tried to add the rationale behind the rules (if it’s omitted, I’ve assumed that it’s pretty obvious).

https://github.com/bbatsov/clojure-style-guide

Web Develoment con Clojure.

Si aunque te parezca raro a este punto, se pueden hacer aplicaciones web con un dialecto de LISP! a puro funciones que llaman otras funciones.

Para hacer web se necesitan varias librerías que vayan resolviendo varios problemas.

En la siguiente charla de la JEEconf da un vistazo rápido de la lógica de .clj para la web.

En la charla el menciona estas librerías:

Luminus un Micro-framework web.

Luminus is a Clojure micro-framework based on a set of lightweight libraries. It aims to provide a robust, scalable, and easy to use platform. With Luminus you can focus on developing your app the way you want without any distractions. — by Luminus

http://www.luminusweb.net/

lein new luminus my-app

Para listar el árbol de archivos del proyecto.

find . -print | sed -e ‘s;[^/]*/;|____;g;s;____|; |;g’

Ring.

Ring is a Clojure web applications library inspired by Python’s WSGI and Ruby’s Rack. By abstracting the details of HTTP into a simple, unified API, Ring allows web applications to be constructed of modular components that can be shared among a variety of applications, web servers, and web frameworks.”
— — James Reeves

https://github.com/ring-clojure

ClojureScript

A este punto, parece que lo más usado para la web es ClojureScript, ya que es un compilado de clojure pero a JavaScript.

Compilar Clojure a JavaScript tiene sus ventajas, porque se puede optimizar el código usando el compilador de Google Closure. Pero como es una historia tan larga, creé otro documento para ir contándola allí, es un borrador:

https://medium.com/@matiasmasca/156f832d4038

PD: Cuando estudie LISP en la Universidad apenas si preste atención, me resulto muy fácil todo y aprobé la materia rápidamente; jamás pensé que 10 años después iba a estar estudiándolo de nuevo por la posibilidad de trabajar de esto.

Otras recursos.

Como obtener tu Cinturón Blanco en Clojure. otra guía bien completa de como iniciarse en este mundo de Clojure.

--

--

Matías Mascazzini
Memorias de un Techie

Workhorse Techie, software developer craftsmanship. I like Ruby http://ruby-lang.org, Ruby On Rails framework & drink mate. He/Him/él.