2 puntos por GN⁺ 2024-05-13 | 1 comentarios | Compartir por WhatsApp

Implementar "Lisp in Lisp" de McCarthy en Python

  • Lisp, desarrollado por John McCarthy a comienzos de los años 60, tiene la característica de la homoiconicidad, por lo que el código y los datos pueden intercambiarse entre sí

    • En Lisp, la frontera entre código y datos se vuelve difusa
    • Gracias a esto, Lisp puede representarse a sí mismo de forma natural
  • La media página de código al pie de la página 13 del manual de Lisp 1.5 era Lisp en sí mismo

    • Alan Kay llamó a esto "las ecuaciones de Maxwell del software"
    • Todo el mundo de la programación está comprimido en apenas unas líneas de código
  • Para entenderlo, una buena forma es reimplementar el código de "Lisp in Lisp" usando Python

    • La mayoría de los programadores no está familiarizada con la sintaxis de Lisp, pero sí con la de Python
    • El objetivo es reescribirlo en Python manteniendo al máximo el espíritu del código Lisp

M-expression y S-expression de Lisp

  • Lisp originalmente tenía dos variantes de sintaxis

    • M-expression (metaexpresión): variante de código
    • S-expression (expresión simbólica): variante de datos
    • Ambas son semánticamente equivalentes
  • El código de "Lisp in Lisp" fue escrito en M-expression e implementa Lisp con S-expression

  • Una forma de hacerlo es convertir la M-expression de Lisp a la estructura de código de Python, y representar las S-expression como listas de Python

    • Lisp significa List Processing, y usa solo una estructura de datos: la lista

Primera implementación

  • Las operaciones básicas de Lisp se implementan con funciones básicas sobre listas de Python

    • atom(x): verifica si x es una lista
    • eq(x,y): verifica si x e y son iguales
    • car(x): devuelve el primer elemento de la lista
    • cdr(x): devuelve el resto de la lista
    • cons(x,y): agrega un átomo a una lista
    • append(x,y): une dos listas
  • Ignorando algunos elementos básicos recursivos, con ayuda de Llama3-70b se puede implementar rápidamente un intérprete para un subconjunto del código de "Lisp in Lisp"

Segunda implementación

  • En la primera implementación falta la funcionalidad de lambda

    • Lambda es la forma principal de definir y llamar funciones en Lisp
    • Sin lambda no se puede implementar recursión, y sin recursión no es Turing completo
  • Para implementar lambda se necesitan los elementos básicos assoc(x,y) y pairlis(x,y)

    • assoc(x,y) es una búsqueda de diccionario key/value usando una lista de asociaciones
    • pairlis(x,y) es equivalente a zip(x,y) en Python
  • Lisp no tiene loop, así que incluso una búsqueda lineal simple debía usar recursión

    • Pero en Python se puede traducir de forma elegante usando list comprehensions
    • Lo mismo aplica para evcon y evlis, que también pueden convertirse en loop
  • La función eval originalmente recibe dos argumentos en Lisp

    • El primero es la expresión (s-exp), y el segundo es el entorno (environment), una lista de key/value
    • El entorno mantiene los enlaces de variables de LAMBDA
    • Usa la técnica de alcance dinámico (dynamic scoping)

Opinión de GN⁺

  • Es un intento interesante de imitar en Python la característica homoicónica de Lisp. Aun así, parece haber límites para trasladar por completo las propiedades únicas de Lisp. Si se quiere experimentar el verdadero atractivo de Lisp, probablemente lo mejor sea aprender Lisp directamente.

  • Resulta impresionante haber implementado en Python funciones potentes de Lisp como lambda y el alcance dinámico. Sin embargo, parece tener bastantes carencias para aplicarlo en proyectos reales. Aun así, se ve valioso con fines educativos o de investigación.

  • Este tipo de intento puede servir como una oportunidad para reflexionar más profundamente sobre la esencia de los lenguajes de programación. Permite mirar más allá de la sintaxis y la implementación, desde la perspectiva de los paradigmas de programación.

  • Aprender lenguajes de la familia Lisp puede ayudar a obtener ideas valiosas sobre programación funcional y metaprogramación. También puede ser buena idea explorar lenguajes Lisp modernos como Scheme, Clojure y Racket.

1 comentarios

 
kayws426 2024-05-13

Un dialecto de Lisp integrado en Python
https://hylang.org/