Los cuatro lenguajes pioneros: LISP

Los cuatro lenguajes pioneros: LISP

Si bien la Inteligencia Artificial es un tema recurrente en la actualidad, fue una disciplina creada mucho antes que las computadoras. Los científicos ya estaban discutiendo modelos matemáticos para definir la inteligencia y, con las computadoras, estas ideas podrían incorporarse a un lenguaje de programación moderno.

LISP es el lenguaje de este artículo y explicaremos cómo sigue siendo influyente en la actualidad.

Inicio de la Inteligencia Artificial

En 1943, McCulloch y Pitts crearon la primera neurona artificial electrónica, dando inicio a lo que ahora conocemos como redes neuronales artificiales. En 1950, Alan Turing propuso en el artículo Computing Machinery and Intelligence, el Juego de Imitación donde una computadora se considera inteligente si logra hacerse pasar por un humano.

Pero el hito en el que podemos definir el nacimiento del campo de estudio de la Inteligencia Artificial fue el seminario de Dartmouth en 1956. En él, destacados matemáticos e informáticos definieron el término Inteligencia Artificial y cuáles son las actividades computacionales que podemos considerar inteligentes.

Todos estos investigadores hicieron modelos y estudios sobre el tema y vieron que las computadoras podían hacer cálculos y procesamientos que hacían posibles muchas ideas. Sin embargo, tenían un problema: carecían de lenguajes de alto nivel para hacer esto, ya que, en ese momento, las computadoras eran difíciles de programar.

En este contexto nació LISP.

(begin

  (display "Hello, LISP!"")

  (newline))

Hello, LISP!

En 1958, el Massachussets Institute of Technology (MIT) estaba lleno de estudios de inteligencia artificial dirigidos por el profesor John McCarthy y necesitaba un lenguaje de alto nivel para estos proyectos. En este contexto surgió el LISt Processor, LISP. Fue implementado por primera vez por Steve Russell en un IBM 704 utilizando tarjetas perforadas.

LISP tiene una base matemática, utilizando el concepto de funciones recursivas y S-expressions. Podemos decir que LISP es un lenguaje de paradigma funcional puro que trabaja con listas de datos, siendo bastante diferente a otros lenguajes de la época.

John McCarthy jogando xadrez contra um computador programado em LISP. Detalhe para a elegância da gravata.
John McCarthy jugando al ajedrez contra una computadora programada en LISP. Nótese la elegancia de la corbata.

LISP ha hecho muchas contribuciones a los lenguajes de programación modernos, comenzando con Macros. Si alguna vez has programado en C/C++, sabes que la macro es un recurso para ampliar el lenguaje en el momento de la precompilación. Básicamente, una macro es una pieza de código que se reemplaza en el código fuente por piezas más complicadas con marcado de macro. Por lo tanto, hace que la lectura y la cantidad de código sean mucho más agradables y reducidas para el programador y también permite recursos adicionales.

Otra contribución es la tipificación dinámica. ¿Qué es esto? Simple, no necesitamos declarar el tipo cuando trabajamos con datos, sino que lo explica por sí mismo.

Ejemplo: 1 es un número entero, pero '1' es un carácter. En otros lenguajes (como Java) es necesario declarar su tipo (int i = 1). Estos lenguajes son tipificados estáticamente.

La última gran contribución está en el intérprete de lenguaje, el Recolector de Basura. Para quienes programan en lenguajes Orientados a Objetos como Java y Python, deben conocer el famoso Garbage Collector (GC - Garbage Collector) que es un recurso que limpia la memoria cuando ya no se utilizan los datos que allí se encuentran.

Como LISP es un gran lenguaje para definir funciones, veamos cómo se vería Factorial en LISP. Aquí usaré LISP 1.5:

(lambda (n)                            # lambda é a indicação de função anônima

    (cond ((eq n 0) 1)               # o if ou condicional é uma função! Se for igual a 0, retorna 1

        (T                                   # T indica um else da condicional

            (mul n                         # Multiplicação pelo valor de entrada N

                (fac (sub n 1))))))    # Aqui temos a recursão: função chamada com N-1

Puedes ver que se trata de funciones y paréntesis.

Aquí podemos notar detalles interesantes: todo en LISP es una función e incluso estructuras conocidas como IF-ELSE se comportan como funciones. Otro punto a tener en cuenta es que las funciones se pasan como argumentos, es decir, la función es un ciudadano de primera clase en lenguaje funcional.

Finalmente, podemos ver la recursividad. Dado que los loops no tienen mucho sentido en la programación funcional, las recursiones cumplen la función de que el código se ejecute varias veces.

Curiosidades

LISP tiene un apodo desagradable: muchos paréntesis estúpidos e irritantes. Como vimos en el código, el punto central de la sintaxis LISP son los paréntesis, lo que genera un debate de amor-odio entre programadores y es motivo de bromas por parte de programadores de otros lenguajes.

Otra curiosidad es la del cocreador de LISP, Stephen Russell, quien fue uno de los artífices de los primeros videojuegos en 1962: ¡Spacewar!.

¡Spacewar!, un juego pionero.

¿LISP sigue vivo?

La respuesta es no. El LISP inicial ya no existe y, como era un lenguaje estudiado y desarrollado en varias universidades americanas para diferentes ordenadores, generó varias versiones nuevas. Debido a la sintaxis simple, todos los LISP tienen una estructura muy similar, por lo que se denominan dialectos LISP. Los más famosos son Common LISP, Scheme, Racket y Clojure.

Sin embargo, tuvo grandes aportes. Uno de ellos fue la apertura del paradigma de programación funcional que generó otros nuevos lenguajes como Haskell y Erlang y otros modernos lenguajes multiparadigmáticos que implementaron parcialmente el paradigma funcional como Javascript, Ruby y Python.

Consulta más información sobre LISP aquí o lee la historia contada por el propio John McCarthy.

¿Conectaste el pasado con el presente?

Para el desarrollo de esta serie de artículos se hizo un trabajo arqueológico sobre los idiomas originales. Lo mejor fue cuando dije: “Ah, de aquí salió esto. ¡Por eso funciona así!”.

Podemos ver que muchos detalles y orígenes de las implementaciones de cada lenguaje moderno fueron fuertemente influenciados por los lenguajes originales debido a cada problema que se creó.

Espero que hayan disfrutado y aprendido un poco más sobre los lenguajes de programación antiguos. Para finalizar esta saga, cuéntennos, ¿cuál de los lenguajes de programación que comentamos en los artículos influyó más en su lenguaje favorito?

⚠️
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Revelo.

Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.