Lisp, abreviatura de "LISt Processing" (Procesamiento de Listas), es una familia de lenguajes de programación que comparten una sintaxis distintiva basada en paréntesis, centrada principalmente en la manipulación de símbolos y listas. Es uno de los lenguajes de programación de alto nivel más antiguos, inventado originalmente a finales de la década de 1950, y ha evolucionado significativamente a lo largo de las décadas. Lisp es particularmente conocido por sus potentes características, como la tipificación dinámica, la recolección de basura y las funciones de primer nivel, lo que lo hace adecuado para la investigación en IA, el cálculo simbólico y el prototipado rápido.
Lisp fue creado por John McCarthy en 1958 como una notación matemática para programas de computadora y como un medio práctico para implementar IA. El lenguaje se derivó del cálculo lambda, un sistema formal en lógica matemática y ciencias de la computación. La primera implementación se realizó en el IBM 704, y poco después, surgieron numerosos dialectos, cada uno añadiendo sus propias características y complejidades.
A lo largo del tiempo, han surgido varios dialectos notables de Lisp, incluidos Common Lisp y Scheme. Common Lisp fue estandarizado en la década de 1980 para unificar varios dialectos, mientras que Scheme, que enfatiza la programación funcional y el minimalismo, ganó popularidad en el ámbito académico. Las influencias de Lisp se pueden ver en muchos lenguajes de programación modernos, especialmente aquellos que soportan paradigmas de programación funcional, como Clojure, Racket e incluso lenguajes como Python y Ruby.
Hoy en día, Lisp no se encuentra entre los lenguajes de programación más populares, pero sigue siendo influyente, particularmente en investigación, IA y educación. La comunidad desarrolla activamente dialectos más nuevos como Clojure, que se ejecuta en la Máquina Virtual de Java (JVM) y se centra en la programación concurrente.
Lisp emplea una sintaxis única que utiliza paréntesis para denotar expresiones, con el código representado en expresiones simbólicas (S-expresiones). Por ejemplo:
(+ 1 2)
Esta expresión representa la adición de 1 y 2.
Las funciones en Lisp pueden ser pasadas como argumentos, devueltas de otras funciones y asignadas a variables:
(defun square (x) (* x x))
(mapcar #'square '(1 2 3 4)) ; devuelve (1 4 9 16)
Lisp es dinámicamente tipado, lo que permite que las variables contengan valores de cualquier tipo de dato sin declaración previa:
(setq x 10) ; x ahora es un número
(setq x "hola") ; x ahora es una cadena
Lisp cuenta con potentes sistemas de macros que permiten a los desarrolladores crear construcciones sintácticas personalizadas:
(defmacro when (condition &body body)
`(if ,condition
(progn ,@body))
)
Las formas if
y cond
facilitan el flujo de control en Lisp:
(if (> x 0)
(print "Positivo")
(print "No positivo"))
Lisp trata las listas como estructuras de datos fundamentales:
(setq my-list '(1 2 3 4))
(car my-list) ; devuelve 1
(cdr my-list) ; devuelve (2 3 4)
Las funciones se definen utilizando la construcción defun
:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Common Lisp incluye un sistema orientado a objetos conocido como el Sistema de Objetos de Common Lisp (CLOS):
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod say-hello ((p person))
(format t "Hola, mi nombre es ~A y tengo ~A años."
(person-name p) (person-age p)))
Lisp proporciona un sofisticado mecanismo de manejo de errores utilizando handler-case
:
(handler-case
(/ 1 0)
(division-by-zero () (print "¡Capturada división por cero!")))
Las continuaciones son soportadas en algunos dialectos, permitiendo que el programa guarde y restaure estados de ejecución:
(call-with-current-continuation
(lambda (k)
(k 10)))
Varios Entornos de Desarrollo Integrados (IDEs) y compiladores están disponibles para la programación en Lisp. Las opciones populares incluyen:
Para construir un proyecto en Lisp, generalmente se crea un archivo con una extensión ".lisp" o ".lsp". Usando SBCL, un flujo de trabajo típico puede implicar cargar tu proyecto desde el REPL:
(load "my-project.lisp")
Para proyectos que utilizan Quicklisp, un gestor de bibliotecas, las dependencias se pueden gestionar y cargar fácilmente.
Lisp es particularmente conocido por sus aplicaciones en inteligencia artificial, cálculo simbólico y academia, pero también se utiliza en:
Lisp a menudo se compara con:
La traducción de Lisp a otros lenguajes a menudo se realiza utilizando herramientas de traducción de código fuente a código fuente. Por ejemplo, existen las siguientes herramientas:
Cada una de estas herramientas proporciona mapeos específicos que aseguran que las funcionalidades centrales de Lisp se puedan representar de manera efectiva en los lenguajes de destino. Para traducciones más complejas, puede ser necesario realizar una refactorización manual, especialmente para código optimizado con macros.