# REPL

Un bucle Lectura-Evaluación-Impresión, REPL por las siglas en inglés de «Read-Eval-Print-Loop», también conocido como alto nivel interactivo o consola de lenguaje, es un entorno de programación interactiva basado en un proceso cíclico donde se lee un fragmento de código ingresado por el usuario, se evalúa y se devuelve un resultado al usuario; las partes de programa escrito en un entorno pueden compartir un estado global mientras el programa esté activo. El término se utiliza normalmente para referirse a interfaces de programación similares al clásico entorno interactivo de programación de la máquina Lisp. Entre los ejemplos comunes se cuentan las interfaces de línea de comandos y entornos similares de lenguajes de programación. Es especialmente característico de los lenguajes de script.

## Resumen

En un REPL, el usuario introduce una expresión, REPL evalúa y muestra el resultado. El nombre «bucle lectura-evaluación-impresión» viene de los nombres de las funciones primitivas de Lisp las cuales implementan esta funcionalidad:
* La función read acepta una expresión del usuario y la parsea en una estructura de datos en memoria. Por ejemplo, el usuario puede introducir la expresión S (+ 1 2 3), la cual es parseada en una lista vinculada que contiene cuatro elementos de información.
* La función eval toma esta estructura de datos interna y la evalúa. En Lisp, evaluar una expresión S que comienza con el nombre de una función significa llamar a dicha función con los argumentos que preparan el resto de la expresión. Así, la función + es llamada con los argumentos 1 2 3, generando el resultado 6.
* La función print toma el resultado obtenido por eval y lo muestra al usuario. Si es una expresión compleja, puede aplicar un formato con estilo para hacerla más sencilla de comprender. En este ejemplo, sin embargo, el número 6 no necesita mucho formateo para ser mostrado.
El entorno de desarrollo, entonces, retorna al estado de lectura, creando un bucle, que termina cuando se cierra el programa.
La utilización de este tipo de entornos facilita la programación explorativa y la depuración, puesto que el programador puede inspeccionar el resultado mostrado antes de decidir qué expresión aportar para la siguiente lectura. El bucle lectura-evaluación-escritura involucra al programador más frecuentemente que el clásico ciclo editar-compilar-ejecutar-depurar.
Puesto que la función print devuelve la información en el mismo formato textual que el utilizado en la función read de entrada de datos, muchos resultado son mostrados en un formato permite, si ello fuera útil, ser copiado y pegado de nuevo hacia el REPL. Sin embargo, a veces es necesario imprimir representaciones de elementos que pueden no ser fácilmente leídos de nuevo, como una gestión de un socket o una compleja instancia de una clase. En estos casos, debe existir una sintaxis para objetos no legibles. En Python, se trata de la notación <__module__.class instance> y en Common Lisp, la figura #<loquesea>. El REPL de CLIM, SLIME y la máquina Lisp pueden también leer de nuevo objetos no legibles. Estos almacenan para cada output qué objeto ha sido mostrado. Después cuando el código es leído de vuelta, el objeto será recuperado desde el output mostrado.
Se pueden crear REPLs compatibles con cualquier lenguaje basado en texto. El soporte de REPL para lenguajes de compilador es comúnmente realizado implementando un intérprete sobre una máquina virtual que provee una interfaz al compilador. Ejemplos de REPLs para lenguajes de compilador serían CINT ─y su sucesor Cling─, ch y BeanShell.

## Uso

Prácticamente todas las consolas UNIX son REPLs para lenguajes de Turing completo. Como una consola, un entorno REPL permite a los usuarios acceder a características relevantes de un sistema operativo además de proveer acceso a funcionalidades de programación.
El uso más extendido para los REPLs fuera de las consolas de sistemas operativos es para prototipado de software instantáneo. Otro usos incluyen cálculo matemático, creación de documentos que integran análisis científico (por ejemplo IPython), mantenimiento de software interactivo, benchmarking y exploración de algoritmos
Un REPL puede convertirse en una parte esencial del aprendizaje de un nuevo lenguaje ya que provee un retroestímulo para el aprendiz.

## Implementación

Para implementar un REPL en Lisp, es necesario únicamente implementar estas tres funciones y una función de bucle infinito (obviamente, la implementación de eval será complicada, dado que se debe también implementar todas las funciones primitivas como car o + y operadores especiales como if.). Hecho esto, un REPL básico es una única línea de código:
Una posible implementación de eval es un intérprete recursivo que actúa sobre el árbol de sintaxis abstracta creado por read. Otra posibilidad es compilar el árbol de sintaxis en código máquina y ejecutarlo.
Las implementaciones reales de REPLs en Lisp son en ocasiones mucho más complicadas.

## Funcionalidades

Funcionalidades típicas provistas por un REPL Lisp incluyen:
* Historial de entradas y salidas.
* Son establecidas variables para las expresiones de entrada y los resultados. Estas variables están también disponibles en el REPL. Por ejemplo, en Common Lisp * se refiere al último resultado, ** y *** a los resultados previos a éste.
* Niveles de REPLs. En varios sistemas Lisp si ocurre un error durante la lectura, evaluación o muestra de resultados de una expresión, el sistema no es traído de vuelta al alto nivel con un mensaje de error. En vez de eso, un nuevo REPL con un nivel de profundidad más es iniciado en el contexto del error. El usuario puede entonces inspeccionar el problema, arreglarlo y continuar -si es posible. Si ocurre un error en dicho REPL de depuración, otro REPL, nuevamente con un nivel de profundidad más, es iniciado. Habitualmente el REPL ofrece comandos especiales de depuración.
* Gestión de errores. El REPL provee reinicios. Estos reinicios pueden ser utilizados cuando ocurre un error para volver a un nivel concreto de REPL.