Elmord's Magic Valley

Software, lingüística e rock'n'roll. Às vezes em Português, sometimes in English.

E esse tal de Lisp?

2012-04-10 01:26 -0300. Tags: comp, prog, lisp, em-portugues

Lisp é um negócio muito doido. Considere o seguinte trecho de código:

(+ 2 3)

Essa é uma expressão que, quando avaliada, produz a soma de 2 e 3. Mas mais que isso, essa expressão é uma lista de três elementos: +, 2 e 3.

Esse é o segredo por trás dos quilos de parênteses das linguagens da família Lisp: enquanto em uma linguagem convencional escrevemos os programas em uma sintaxe especial (e.g., 2+3), que é convertida em uma árvore sintática durante a compilação ou interpretação, em Lisp escrevemos a árvore sintática diretamente, usando uma notação uniforme de listas aninhadas. Quando escrevemos 2*3+4*5 em uma linguagem convencional, o compilador/interpretador produz internamente uma estrutura de dados muito similar ao (+ (* 2 3) (* 4 5)) do Lisp.

Aí você se pergunta: por que escrever a árvore sintática diretamente, se o compilador pode fazer isso por mim? Uma resposta é que escrever a árvore sintática diretamente torna a vida de quem escreve o compilador mais fácil. A segunda questão é: o que é que eu tenho a ver com isso? A reposta é que, em Lisp, quem escreve o compilador é VOCÊ!!

A principal característica que distingue os Lisps da maior parte das linguagens de programação é a extensibilidade: você pode adicionar novas construções sintáticas à linguagem, sem ter que alterar o compilador, através do mecanismo de macros. Macros em Lisp não são como as macros localizar-e-substituir do C. As macros do Lisp são funções, que recebem como entrada um trecho de código, e retornam como saída outro trecho de código. Definindo macros, você pode estender a linguagem como bem entender. E como a estrutura do código é uniformemente expressa por listas, você não precisa se preocupar em parsear texto; a macro já recebe a lista parseada que representa o código como entrada.

Por exemplo, imagine que você está programando em uma linguagem sem while. Teoricamente, você não precisa de while se você tiver if e goto. Na prática, é conveniente ter uma construção pronta ao invés de escrever o código com if/goto toda vez. Em uma linguagem como C, se o while não for um comando embutido na linguagem, não há o que fazer; para adicionar o while, teríamos que alterar o compilador. Porém, a transformação de um while em um if/goto é trivial, e poderia ser facilmente automatizada:

while (teste) {     =>    loopstart:
    comando1;               if (teste) {
    comando2;                   comando1;
}                               comando2;
                                goto loopstart;
                            }

A idéia da macro é permitir ao programador adicionar transformações de código desse tipo à linguagem. Em Common Lisp, a transformação que queremos é:

(while teste       =>    (tagbody loopstart
  comando1                 (when teste
  comando2)                  comando1
                             comando2
                             (go loopstart))

Essa transformação pode ser expressa com a seguinte macro:

(defmacro while (test &body body)
  `(tagbody loopstart
     (when ,test
       ,@body
       (go loopstart))))

Embora esse seja um exemplo simples, similar a uma macro localizar-e-substituir, uma macro pode realizar qualquer tipo de transformação no código. A macro é simplesmente uma função que transforma trechos de código em outros trechos de código, e tudo o que pode ser feito por uma função pode ser feito em uma macro. É possível implementar sub-linguagens com macros; por exemplo, poder-se-ia implementar uma macro para converter queries numa sintaxe SQL-like em código correspondente para realizar a query em um banco de dados. (De fato, existem bibliotecas que fazem isso em Common Lisp.) Macros executam em tempo de compilação, e portanto podem ser arbitrariamente complexas sem afetar o desempenho do código em tempo de execução (desde que o código retornado pela macro seja eficiente). As possibilidades são infinitas.

Se você tiver interesse na linguagem, recomendo ler o Practical Common Lisp. Fica o alerta ao leitor: Lisp é um negócio bizarro à primeira vista. Common Lisp, em particular, não é lá muito bonitinho e consistente em alguns aspectos (embora faça muito mais sentido com o tempo do que pode parecer inicialmente). Se você quiser aprender a linguagem a fundo, terá que se aproximar dela com a mente aberta e dar-lhe o benefício da dúvida em algumas ocasiões. Em verdade vos digo: vale muito a pena.

Comentários / Comments (0)

Deixe um comentário / Leave a comment

Main menu

Posts recentes

Comentários recentes

Tags

em-portugues (213) comp (138) prog (68) in-english (51) life (47) unix (35) pldesign (35) lang (32) random (28) about (27) mind (25) lisp (23) mundane (22) fenius (20) web (18) ramble (17) img (13) rant (12) hel (12) privacy (10) scheme (10) freedom (8) bash (7) copyright (7) music (7) academia (7) lash (7) esperanto (7) home (6) mestrado (6) shell (6) conlang (5) emacs (5) misc (5) latex (4) editor (4) book (4) php (4) worldly (4) politics (4) android (4) etymology (4) wrong (3) security (3) tour-de-scheme (3) kbd (3) c (3) film (3) network (3) cook (2) poem (2) physics (2) wm (2) treta (2) philosophy (2) comic (2) lows (2) llvm (2) perl (1) en-esperanto (1) audio (1) german (1) kindle (1) old-chinese (1) pointless (1) translation (1)

Elsewhere

Quod vide


Copyright © 2010-2020 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

Powered by Blognir.