REPL: Read-Eval-Print-Loop


Instalando Lisp

Puestos a programar en Common Lisp, existen varias opciones libres:

Cualquier entorno Lisp requiere de un intérprete que siga el ciclo leer-evaluar-imprimir; primero lee las instrucciones escritas por el programador, luego las ejecuta y, finalmente, imprime los resultados obtenidos, quedando entonces en un estado de espera a que el programador vuelva a escribir una sentencia y ejecutar nuevamente el ciclo leer-evaluar-imprimir.

En estas páginas haré uso de SBCL (Steel Bank Common Lisp). SBCL no solo es un intérprete, sino también un compilador, lo cual significa que cualquier programa escrito con él puede guardarse en código máquina y ser ejecutado de forma independiente y más rápida. La mayoría de los entornos Lisp actuales son también compiladores.

Aunque los códigos incluidos en estas páginas están ejecutados en una máquina Linux, deberían funcionar también en otros sistemas operativos. SBCL, CLISP o ECL tienen versiones para Windows.

Para instalar SBCL en una máquina Linux basada en Debian, tal como Ubuntu, la instalación de SBCL es tan sencilla como abrir un terminal y ejecutar en él la instrucción

sudo apt install rlwrap sbcl

Ya está. Para entrar en el intérprete, basta ejecutar la siguiente orden desde el terminal:

rlwrap sbcl

y veremos esto:

This is SBCL 1.3.1.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at .

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* 

El asterisco (el prompt) nos indica que está esperando una instrucción por parte de su interlocutor biológico. Le pedimos que sume uno más uno y luego pulsamos la tecla de retorno; se ejecutará entonces el ciclo Read-Eval-Print y obtendremos el resultado:

* (+ 1 1)   

2
* 

Nos devuelve dos y otra vez el asterisco esperando nueva entrada. A partir de ahora obviaremos reproducir el asterisco para facilitar la lectura.

Listo. Ya tenemos un entorno Lisp en nuestro sistema totalmente operativo.

El lector ya habrá advertido la forma extraña en la que se ha invocado la función de sumar. Estamos acostumbrados, tanto en matemáticas como en cualquier otro lenguaje de programación, a escribir funciones en la forma f(x). Lisp no utiliza este formato; aquí debemos escribir (f x). La razón estriba en que en Lisp no hay diferencia sustancial entre datos y funciones; una lista encerrada entre paréntesis siempre son datos, independientemente de que se trate de la lista de la compra o de un programa de inteligencia artificial. Así, un programa puede ser manipulado por otro programa porque lo puede modificar igual que lo podría hacer con una lista de objetos. Esta es la razón por la que a veces se dice que Lisp es un lenguaje de programación programable. ¿Se da cuenta el lector de lo refinada de la idea? Así es Lisp.

Menú de error

Es frecuente cometer errores y pasarle al intérprete instrucciones que éste no puede ejecutar. Es entonces cuando se le presenta un menú al usuario que éste debe entender. Este menú es distinto de un intérprete a otro, pero nosotros nos centramos en el de SBCL, que es el que tenemmos instalado.

Supongamos que al solicitar la suma de más arriba, sin querer volvemos a escribir un segundo paréntesis justo antes de pulsar la tecla de retorno. Hemos introducido un error sintáctico que SBCL nos lo hace saber:

(+ 1 1))
2
* 
debugger invoked on a SB-INT:SIMPLE-READER-ERROR in thread
#:
  unmatched close parenthesis

    Stream: #

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-INT:SIMPLE-READER-ERROR # "unmatched close parenthesis")
0]

Es un poco lío, pero al entrar en el modo de depuración nos avisa de que hay un paréntesis mal emparejado (unmatched close parenthesis), de que podemos escribir HELP para obtener ayuda sobre cómo trabajar con el depurador de errores, de que también podemos escribir (SB-EXT:EXIT) para terminar con la sesión de SBCL y volver a la línea de comandos del sistema, y por último, que si pulsamos 0 o ABORT, podemos abortar la ejecución de la instrucción anterior y volver al intérprete Lisp. Nosotros optamos por esto último:

...............
0] 0
*

Y ya lo tenemos con el asterisco esperando una nueva instrucción.

Vamos a ejecutar nuevamente la suma de uno más uno pero corrigiendo previamente el error sintáctico. Para ello pulsamos la tecla de cursor hacia arriba repetidamente hasta que aparezca la instrucción a editar, la corregimos y volvemos a pulsar la tecla de retorno. Esto es lo que se debería ver:

* (+ 1 1)

2
* 

Múltiples líneas

Si se necesita escribir una instrucción larga, podemos editarla en tantas líneas como sea necesario, siempre pulsando la tecla de retorno para introducir una nueva. El intérprete no intentará ejecutarla hasta que el primer paréntesis quede emparejado con el último.

Si queremos calcular la expresión 3 + 5·4 + 6, podemos hacer lo siguiente,

(+ 3
   (* 5 4)
   6 )
29

Una vez el cursor se sitúa en una nueva línea, ya no es posible editar las superiores. En programas que abarcan muchas líneas, la costumbre es escribirlos utilizando un editor de textos y guardarlos en un fichero, luego se llama al intérprete para que lo ejecute. Nadie hace un programa serio escribiendo directamente en el intérprete.

Fin de la sesión

Para salir,

(quit)

La función quit no tiene argumentos, por lo que solo se escribe su nombre entre paréntesis.


© 2016, TecnoStats