2 pontos por GN⁺ 2024-05-13 | 1 comentários | Compartilhar no WhatsApp

Implementando o "Lisp in Lisp" de McCarthy em Python

  • O Lisp, desenvolvido por John McCarthy no início da década de 1960, possui a característica de homoiconicidade, em que código e dados podem ser intercambiáveis

    • No Lisp, a fronteira entre código e dados fica difusa
    • Com isso, o Lisp consegue representar a si mesmo de forma natural
  • Meio página de código no rodapé da página 13 do manual do Lisp 1.5 era o próprio Lisp

    • Alan Kay chamou isso de "as equações de Maxwell do software"
    • Todo o universo da programação está comprimido em apenas algumas linhas de código
  • Para entender isso, uma boa forma é reimplementar em Python o código de "Lisp in Lisp"

    • A maioria dos programadores não está acostumada com a sintaxe do Lisp, mas provavelmente está com a do Python
    • O objetivo é reescrever em Python preservando ao máximo o espírito do código Lisp

M-expression e S-expression do Lisp

  • Originalmente, o Lisp tinha dois sabores de sintaxe

    • M-expression (metaexpressão): o sabor de código
    • S-expression (expressão simbólica): o sabor de dados
    • As duas são semanticamente equivalentes
  • O código de "Lisp in Lisp" foi escrito em M-expression e implementa Lisp com S-expression

  • Uma forma de fazer isso é converter a estrutura de M-expression do Lisp em estrutura de código Python, e representar S-expression como listas Python

    • Lisp significa List Processing e usa apenas uma única estrutura de dados: listas

Primeira implementação

  • As operações básicas do Lisp foram implementadas com funções básicas de listas do Python

    • atom(x): verifica se x é uma lista
    • eq(x,y): verifica se x e y são iguais
    • car(x): retorna o primeiro elemento da lista
    • cdr(x): retorna o restante da lista
    • cons(x,y): adiciona um átomo à lista
    • append(x,y): concatena duas listas
  • Ignorando alguns elementos básicos recursivos, é possível implementar rapidamente um interpretador para um subconjunto do código "Lisp in Lisp" com ajuda do Llama3-70b

Segunda implementação

  • A primeira implementação não tinha suporte a lambda

    • Lambda é a principal forma de definir e chamar funções no Lisp
    • Sem lambda não dá para implementar recursão, e sem recursão não há completude de Turing
  • Para implementar lambda, são necessários os elementos básicos assoc(x,y) e pairlis(x,y)

    • assoc(x,y) é uma busca de chave/valor em dicionário usando lista de associação
    • pairlis(x,y) é equivalente a zip(x,y) em Python
  • Como o Lisp não tinha loop, até uma busca linear simples precisava usar recursão

    • Mas em Python isso pode ser convertido elegantemente com list comprehensions
    • O mesmo vale para evcon e evlis, que também podem ser convertidos em loops
  • A função eval originalmente recebe dois argumentos no Lisp

    • O primeiro é a expressão (s-exp), o segundo é o ambiente (environment), uma lista de chave/valor
    • O ambiente mantém os vínculos de variáveis de LAMBDA
    • Usa a técnica de escopo dinâmico (dynamic scoping)

Opinião do GN⁺

  • É uma tentativa interessante de imitar em Python a característica de homoiconicidade do Lisp. Ainda assim, parece haver limites para transportar perfeitamente as características exclusivas do Lisp. Para experimentar o charme do Lisp, o melhor continua sendo aprender o próprio Lisp.

  • É impressionante ter implementado em Python recursos poderosos do Lisp, como funções lambda e escopo dinâmico. Mas parece haver muitas limitações para aplicar isso em projetos reais. Para fins educacionais ou de pesquisa, parece ter valor.

  • Esse tipo de tentativa pode servir como oportunidade para refletir profundamente sobre a essência das linguagens de programação. Independentemente da sintaxe e da implementação da linguagem, isso permite adotar uma visão a partir do paradigma de programação.

  • Aprender linguagens da família Lisp pode ajudar a obter insights sobre programação funcional e metaprogramação. Também vale a pena olhar para linguagens Lisp modernas como Scheme, Clojure e Racket.

1 comentários

 
kayws426 2024-05-13

Uma variação de Lisp incorporada ao Python
https://hylang.org/