Resposta ao exercício 79

Uma vez que os parâmetros &key podem ser inicializados e a sintaxe é igual à usada na ficha, basta modificar o construtor e passar apenas os nomes dos campos (esquecendo as inicializações por omissão) às restantes funções.

(defun nome-campo (campo)
  (if (listp campo) (first campo) campo))

(defmacro ficha (nome &rest campos) (let ((nomes-campos (mapcar #'nome-campo campos))) `(progn ,(construtor-ficha nome nomes-campos campos) ,@(selectores-ficha nome nomes-campos) ,@(modificadores-ficha nome nomes-campos) ,(reconhecedor-ficha nome) ',nome))

(defun construtor-ficha (nome nomes-campos campos) `(defun ,(junta-nomes 'novo- nome) (&key ,@campos) (list ',nome ,@nomes-campos)))

> (macroexpand-1 '(ficha automovel marca modelo (portas 4)))) (PROGN (DEFUN NOVO-AUTOMOVEL (&KEY MARCA MODELO (PORTAS 4)) (LIST 'AUTOMOVEL MARCA MODELO PORTAS)) (DEFUN AUTOMOVEL-MARCA (AUTOMOVEL) (NTH 1 AUTOMOVEL)) ...

Esta forma de criação de fichas já existe em Common Lisp através da macro defstruct.