Seguinte: Macros Úteis Acima: Macros Anterior: Depuração de Macros
Índice remissivo

Caracteres de Macro

Geralmente, a parte mais difícil na escrita de uma macro é a determinação das expressões Lisp que quando avaliadas produzem uma nova expressão Lisp que realiza o nosso objectivo. Para simplificar esta tarefa é usual utilizarem-se caracteres especiais que, à semelhança da plica (quote) e do cardinal-plica (function) são transformados na leitura para outras expressões. Cada um dos caracteres especiais possui uma função Lisp associada que é avaliada quando a linguagem, durante a leitura das expressões, encontra um desses caracteres. Essa função Lisp pode então realizar mais leituras e retornar o que achar mais conveniente.

Estes caracteres especiais são designados caracteres de macro pois eles são transformados (são expandidos) na leitura em outras expressões, um pouco à imagem do que acontecia com as macros. A diferenção está no instante em que a expansão ocorre. Uma macro é expandida em tempo de compilação (ou, em algumas implementações de Lisp, em tempo de execução). Um carácter de macro é expandido na leitura de expressões.

Qualquer carácter pode ser considerado especial, bastando, para isso, usar a função set-macro-caracter que recebe um carácter e uma função a aplicar sempre que o carácter for lido. A função a aplicar deve possuir dois parâmetros que receberão, o primeiro, o local donde o Lisp estava a ler (terminal, ficheiro, etc) para que a função possa continuar a leitura do mesmo sítio, e o segundo, o próprio carácter de macro.

Para se indicar um carácter em Lisp é necessário precedê-lo dos caracteres ``#\''. Por exemplo, o carácter $ é indicado por ``#\$''. Como já é sabido, se não se incluíssem os caracteres ``#\'', o Lisp consideraria o objecto lido como um símbolo e não como um carácter.

Para se compreender a utilização dos caracteres de macro, podemos admitir que não existia o carácter de plica e que pretendíamos defini-lo. A expressão 'ola representa, como sabemos, (quote ola), logo a função que seria invocada quando se encontrasse a plica necessitaria de ler o objecto que estava após a plica (usando a função read) e construiria uma lista com o símbolo quote à cabeça e o objecto lido no fim, ou seja:

(defun plica (canal-leitura caracter)
  (list (quote quote) (read canal-leitura)))

> (set-macro-character #´ (function plica)) T > 'ola OLA

A linguagem Lisp possui, previamente definidos, vários caracteres de macro. A plica é um deles, o ponto e vírgula (que representa um comentário) é outro, etc. Alguns dos caracteres de macro são precedidos por um carácter especial, considerado o carácter de despacho, permitindo aumentar o número de possíveis caracteres de macro sem reduzir o número de caracteres normais utilizáveis. O carácter de despacho mais usado é o cardinal, mas pode ser qualquer outro. Como exemplos destes caracteres de macro com despacho temos o cardinal-plica para indicar funções, o cardinal-barra para indicar caracteres, etc.

De todos os caracteres de macro, aqueles que são particularmente úteis para a escrita de macros são o plica para trás (`--backquote), a vírgula (,--comma) e o vírgula-arroba (,@--comma-at).

O backquote indica ao avaliador que não deve avaliar uma expressão excepto quando for indicado em contrário. Quando usado isoladamente, o backquote funciona exactamente como o quote. No entanto, a sua combinação com o comma e o comma-at permite simplificar imenso a escrita de expressões complexas. O comma só pode ser utilizado numa expressão (uma lista, tipicamente) precedida do backquote, e informa o avaliador que a expressão que se segue é para avaliar e o seu resultado inserido na lista. O comma-at é idêntico mas o resultado da avaliação tem de ser uma lista cujos elementos são inseridos.

A título de exemplo, temos:

> `((+ 1 2) ,(+ 1 2) (list 1 2) ,(list 1 2) ,@(list 1 2))
((+ 1 2) 3 (LIST 1 2) (1 2) 1 2)

Seguinte: Macros Úteis Acima: Macros Anterior: Depuração de Macros
Índice remissivo

Copyright António Leitão, 1995