Loading...

¿QUÉ HIZO DIFERENTE A LISP?

Original

Diciembre de 2001 (revisión de mayo de 2002)

(Este artículo surgió como respuesta a algunas preguntas en la lista de correo LL1 . Ahora está incorporado en Revenge of the Nerds ).

Cuando McCarthy diseñó Lisp a finales de la década de 1950, supuso un cambio radical respecto de los lenguajes existentes, el más importante de los cuales era Fortran .

Lisp incorporó nueve ideas nuevas:

1. Condicionales. Un condicional es una construcción if-then-else. Hoy en día lo damos por sentado. Fue inventado por McCarthy durante el desarrollo de Lisp. (Fortran en ese momento solo tenía un condicional goto, basado en la instrucción de bifurcación del hardware subyacente). McCarthy, que estaba en el comité de Algol, introdujo los condicionales en Algol, desde donde se extendieron a la mayoría de los demás lenguajes.

2. Un tipo de función. En Lisp, las funciones son objetos de primera clase: son un tipo de datos como los números enteros, las cadenas, etc., y tienen una representación literal, se pueden almacenar en variables, se pueden pasar como argumentos, etc.

3. Recursión. La recursión existía como concepto matemático antes de Lisp, por supuesto, pero Lisp fue el primer lenguaje de programación que la admitió (podría decirse que está implícita en la conversión de funciones en objetos de primera clase).

4. Un nuevo concepto de variables. En Lisp, todas las variables son efectivamente punteros. Los valores son lo que tiene tipos, no las variables, y asignar o vincular variables significa copiar punteros, no aquello a lo que apuntan.

5. Recolección de basura.

6. Programas compuestos de expresiones. Los programas Lisp son árboles de expresiones, cada una de las cuales devuelve un valor. (En algunos Lisp, las expresiones pueden devolver múltiples valores). Esto contrasta con Fortran y la mayoría de los lenguajes posteriores, que distinguen entre expresiones y sentencias.

Era natural tener esta distinción en Fortran porque (no es sorprendente que en un lenguaje donde el formato de entrada eran tarjetas perforadas) el lenguaje estaba orientado a líneas. No se podían anidar instrucciones. Y, por lo tanto, aunque se necesitaban expresiones para que las matemáticas funcionaran, no tenía sentido hacer que cualquier otra cosa devolviera un valor, porque no podía haber nada esperando por ello.

Esta limitación desapareció con la llegada de los lenguajes estructurados en bloques, pero para entonces ya era demasiado tarde. La distinción entre expresiones y enunciados estaba arraigada. Se extendió de Fortran a Algol y de allí a sus dos descendientes.

Cuando un lenguaje está compuesto completamente de expresiones, puedes componer expresiones como quieras. Puedes decir cualquiera de las dos cosas (usando la sintaxis de Arc )

(si foo (= x 1) (= x 2))

o

(= x (si foo 1 2))

7. Un tipo de símbolo. Los símbolos se diferencian de las cadenas en que se puede comprobar la igualdad comparando un puntero.

8. Una notación para código que utiliza árboles de símbolos.

9. Todo el lenguaje siempre disponible. No existe una distinción real entre tiempo de lectura, tiempo de compilación y tiempo de ejecución. Puedes compilar o ejecutar código mientras lees, leer o ejecutar código mientras compilas y leer o compilar código en tiempo de ejecución.

La ejecución de código en tiempo de lectura permite a los usuarios reprogramar la sintaxis de Lisp; la ejecución de código en tiempo de compilación es la base de las macros; la compilación en tiempo de ejecución es la base del uso de Lisp como lenguaje de extensión en programas como Emacs; y la lectura en tiempo de ejecución permite a los programas comunicarse usando expresiones s, una idea recientemente reinventada como XML.

Cuando se inventó Lisp, todas estas ideas estaban muy alejadas de la práctica de programación habitual, que estaba dictada en gran medida por el hardware disponible a fines de la década de 1950.

Con el tiempo, el lenguaje predeterminado, plasmado en una sucesión de lenguajes populares, ha evolucionado gradualmente hacia Lisp. Los lenguajes 1 a 5 están ahora muy extendidos. El 6 está empezando a aparecer en la corriente principal. Python tiene una forma de 7, aunque no parece haber ninguna sintaxis para él. El 8, que (junto con el 9) es lo que hace posibles las macros de Lisp, hasta ahora sigue siendo exclusivo de Lisp, quizás porque (a) requiere esos paréntesis, o algo igual de malo, y (b) si agregas ese incremento final de potencia, ya no puedes afirmar que has inventado un nuevo lenguaje, sino solo que has diseñado un nuevo dialecto de Lisp ; -)

Aunque resulta útil para los programadores actuales, resulta extraño describir Lisp en términos de su variación de los recursos aleatorios que adoptaron otros lenguajes. Probablemente, McCarthy no lo pensó así. Lisp no fue diseñado para corregir los errores de Fortran; surgió más bien como subproducto de un intento de axiomatizar la computación .