Notxor tiene un blog

Defenestrando la vida

A vueltas con ecl

Notxor
2023-08-29

El otro día hablé sobre un par de sistemas embebibles, chibi-scheme y ecl. Hay quien se ha interesado en el tema, pero por las preguntas que me han hecho creo que no me expliqué bien en ese artículo. Hoy intentaré aclarar algunos puntos que gracias a mi torpeza habitual quedaron un tanto confusos... será un artículo cortito.

Los aspectos que trataré serán los siguientes:

  1. Embebible no significa que no funcionen si no están embebidos.
  2. Compilables: pueden generar binarios ejecutables directamente.
  3. Cuáles uso y por qué.

Porque soy así de congruente, comenzaré por el tercer y último punto. La razón, además de mi habitual desorden, es que es la más fácil de redactar, puesto que está más relacionado con mis gustos que con aspectos técnicos.

Qué uso y por qué

Mis herramientas, o chismáticos/, para trabajar son sencillas. Habitualmente cuento con un ordenador portátil, una tableta y un móvil. El portátil tiene instalada una distro GNU/Linux OpenSuse Tumbleweed. Hasta hace no mucho, tanto el móvil como la tableta tenían instalado como SO Ubuntu Touch. Sin embargo, la vida de los aparatos electrónicos es efímera y ambos pasaron a mejor vida después de unos cuantos años de uso. Actualmente, tanto mi móvil como mi tableta corren con Android®.

En mi trabajo debo generar bastantes documentos, lo que me obliga a un uso intensivo de Emacs. No sólo esto, además utilizo org-mode para la agenda, toma de notas, etc. La mayor parte de las herramientas que me he tenido que hacer para automatizar mi día a día, están hechas con emacs-lisp, pero algunas pocas están programadas en otros lenguajes. Es decir, cuando he necesitado crearme alguna herramienta más, especialmente para cálculos o acceder a bases de datos he utilizado otros lenguajes. De esta manera tengo scripts hechos en Python, en erlang, uno o dos en Tcl/Tk y otros pocos en scheme.

Llevo tiempo queriendo unificar todos esos scripts y tareas en una aplicación que se convertiría en una especie de gestor de historias clínicas y otras tareas propias del (psicólogo) autónomo, como puede ser la facturación. Dicha aplicación debe correr en el portátil y también en la tableta y, posiblemente, el teléfono. En estos dos últimos con Termux podría desarrollar dichas propias herramientas. No necesitaría GUI, aunque sería de agradecer, y por tanto, estoy un poco sujeto a qué puede correr en dicha aplicación de Android®.

Al elegir herramientas, como digo, estoy limitado. Podría haber elegido erlang, que también corre en Termux, pero erlang demuestra su potencia en aplicaciones de red, que no es el caso. Además llevo tiempo haciendo mis pinitos con SBCL y me encuentro más cómodo con Common Lisp. Sin embargo en Termux el CL que se puede encontrar es ECL, por lo que comencé a echarle un ojo... y me gusta.

El scheme que más utilizo es Chicken Scheme principalmente por sus huevos... los eggs forman el sistema de paquetería. En Termux hay varios Scheme instalables:

  • Chicken
  • gauche
  • guile
  • racket
  • tinyscheme

Sin embargo, las opciones con Lisp son más escasas y tan sólo ECL es un Common Lisp:

  • ECL
  • fennel: genera código Lua
  • ol: Dialecto de Lisp
  • PicoLisp: intérprete de Lisp no estándar

Miré por encima picolisp, y a primera vista tiene también muy buena pinta, pero el que no cumpla estándares me hecha un poco para atrás. Sin embargo, es un sistema que tengo que echarle un ojo más despacio.

Después de todo este rollo, podría haber resumido con una respuesta mucho más escueta: «uso chicken y ecl en android® y sbcl en GNU/Linux».

Embebido y compilación

Dichas herramientas tienen la capacidad de funcionar como una librería que podemos añadir a nuestros programas y que funcionar como un lenguaje de extensión para la aplicación. Pero que tengan dicha capacidad no significa que sólo funcionen de dicha manera. Al contrario: ambos cuentan con herramienta REPL, capacidad de ejecución como script interpretado y, además, capacidad de compilado.

Dicho de otro modo: que tengan la capacidad de «funcionar como» no implica que las tengas que utilizar sólamente de ese modo. En ambas herramientas, tanto en Chicken como en ECL puedes compilar a binario un script, pero raramente utilizo esa característica, porque no lo necesito. Es decir, entiendo que la compilación está bien para darle a alguien un binario y que no necesite instalarse el sistema. Pero en mi caso, ya tengo instalado el sistema y raramente hago cálculos tan intensivos que necesite compilar para ahorrarme uno o dos segundos de tiempo.

Sin embargo, para responder a otra pregunta que me han hecho, explicaré cómo compilar un script o programa con estos sistemas. En el caso de Chicken es sencillo, tan sólo tienes que utilizar el compilador que proporciona: csc y se pueden generar archivos .o, llamar al compilador desde make, etc. Desde ECL, las cosas son algo distintas: el compilador está embebido en el intérprete y por tanto, para compilar debes crearte un script que genere el ejecutable.

Vamos a poner un ejemplo para no hablar en vacío. Para no liarme a programar más allá de lo estrictamente necesario, parto del mismo código que calcula el factorial de un número. Bueno, el mismo no, pero muy parecido al código del otro día:

;;; archivo factorial.lisp

(defun factorial (x)
  (labels ((itera (n total)
             (if (= n 0)
                 total
                 (itera (- n 1) (* total n)))))
    (itera x 1)))

(defun principal ()
  (print (factorial 2000))
  (quit))

(principal)

El código para generar el binario ejecutable sería:

;;; generar «factorial.o»
(compile-file "factorial.lisp"
              :system-p t)

;;; generar el binario «fact»
(c:build-program "fact"
                 :lisp-files '("factorial.o"))

La forma compile-file genera binarios .o a partir de los fuentes Lisp. Para hacerlo es importante tener activada la opción :system-p, porque si no es así, compilará el archivo a byte-code fasl. El parámetro que recibe es el nombre del archivo.

Para generar el ejecutable se llama a c:build-program. El parámetro que recibe es el nombre del ejecutable. :lisp-files es una lista de los ficheros .o necesarios para armarlo.

Igual que se pueden generar ejecutables, también se pueden hacer librerías con las formas c:build-static-library y c:build-shared-library. Pero eso es otra historia que ahora mismo no viene al caso.

Otras consideraciones

En general, los sistemas de la familia Lisp se pueden considerar los padres de la programación funcional, pero la mayoría soportan la programación orientada a objetos (POO). CLOS1 para unos y SOS2 para otros. En este sentido, me llamó la atención de PicoLisp el que lleve dicho sistema ya embebido y que las variables puedan tener propiedades con valor. Esto hace que las estructuras de datos puedan ser realmente complejas y es algo que tengo que investigar un poco más antes de decidirme por algo.

De momento, no puedo clasificar a PicoLisp ni entre los Lisp, ni entre los Scheme, pero debo estudiarlo un poco más antes de decidir, incluso, si me gusta o no. He visto que es un sistema en desarrollo desde 1988, lo que da garantía de estabilidad. He visto que es rápido para ser únicamente interpretado. Le tengo que trastear un poco más y ya contaré aquí en el blog mis impresiones.

Conclusión

Utilizar estas herramientas u otras está más relacionado con la comodidad del usuario, o con la moda, muchas veces, que con otras consideraciones. Nos movemos por gustos y costumbres, nos mantenemos en nuestra zona de confort porque, generalmente, somos más productivos en ella. Una herramienta nos puede ayudar más o menos pero siempre nos va a costar más cambiar, dando un salto a lo desconocido, donde no sabemos cómo nos saldrán los planes.

En este sentido, por ejemplo, cuando estuve mirando PicoLisp, me pareció un sistema bastante interesante y prometedor, como ya dije antes. Si hubiera seguido un estándar como CL o como Scheme, seguramente lo hubiera probado más a fondo de lo que lo he hecho hasta ahora y tendría una opinión más formada sobre ello.

En estos aspectos, no tengo muchos reparos a salir de mi zona de confort para probar cosas nuevas. Eso lo aprendí cuando siendo un usuario convencido de Vim3 probé, dedicándole el suficiente tiempo, Emacs y me encontré un sistema mucho mejor para mis necesidades. No descarto, por tanto, el investigar otros derroteros, para mis cosas y no tengo una fecha límite de entrega de ningún trabajo. Por tanto, me puedo dedicar a aprender lenguajes, a cacharrear y ampliar mi caja de herramientas.

Notas al pie de página:

1

Common Lisp Object System

2

Scheme Object System

3

Sigo siéndolo, pero ya no es el editor por defecto en mis entornos.

Categoría: lisp

Comentarios

Debido a algunos ataques mailintencionados a través de la herramienta de comentarios, he decidido no proporcionar dicha opción en el Blog. Si alguien quiere comentar algo, me puede encontrar en esta cuenta de Mastodon, también en esta otra cuenta de Mastodon y en Diaspora con el nick de Notxor.

Si usas habitualmente XMPP (si no, te recomiendo que lo hagas), puedes encontrar también un pequeño grupo en el siguiente enlace: notxor-tiene-un-blog@salas.suchat.org

Disculpen las molestias.