En mi búsqueda para comprender completamente las poderosas macros de lisp, una pregunta vino a mi mente. Sé que una regla de oro sobre macros es la que dice "Nunca use una macro cuando una función hará el trabajo". Sin embargo, al leer el Capítulo 9 - Practical: Building a Unit Test Framework - del libro Practical Common Lisp, se presentó el siguiente macro cuyo objetivo era eliminar la duplicación de la expresión de caso de prueba, con el consiguiente riesgo de etiquetar incorrectamente los resultados.Lisp: macros vs funciones
;; Function defintion.
(defun report-result (result form)
(format t "~:[FAIL~;pass~] ... ~a~%" result form))
;; Macro Definition
(defmacro check (form)
`(report-result ,form ',form))
OK, entiendo su propósito, pero que podría haber hecho que el uso de una función en lugar de una macro, por ejemplo:
(setf unevaluated.form '(= 2 (+ 2 3)))
(defun my-func (unevaluated.form)
(report-result (eval unevaluated.form) unevaluated.form))
- ¿Es esto sólo es posible porque la macro dado es demasiado simple ?
- Además, ¿el Sistema Macro de Lisp es tan poderoso que sus oponentes debido al código en sí, como estructuras de control, funciones, etc., se representa como una LISTA?
Esta "regla de oro" es estúpida. Use macros donde los encuentre apropiados y olvídese de todas las "reglas" dañadas por el cerebro. En cuanto a su ejemplo, no es casi equivalente, ya que está posponiendo una compilación al tiempo de ejecución. Si su formulario contiene referencias a algunos nombres de ámbito local, simplemente no funcionará. –
Sk, ¿podría dar un ejemplo con respecto a la función eval y el nombre del ámbito local? – utxeee
'(let ((x 2)) (eval '(+ x x)))' simplemente no funcionaría, OTOH si este formulario '(+ x x)' fue generado por una macro, sería compilado naturalmente. –