W moim dążeniu do pełnego zrozumienia tak potężnych makr lispów przyszło mi do głowy pytanie. Wiem, że złotą zasadą dotyczącą makr jest ta, która mówi: "Nigdy nie używaj makra, gdy funkcja wykona pracę". Jednak czytając rozdział 9 - - z książki Practical Common Lisp zostałem wprowadzony do poniższego makra, którego celem było pozbyć się powielania wyrażenia przypadku testowego, z towarzyszącym mu ryzykiem błędnego oznakowania wyników.Lisp: Makra kontra funkcje
;; Function defintion.
(defun report-result (result form)
(format t "~:[FAIL~;pass~] ... ~a~%" result form))
;; Macro Definition
(defmacro check (form)
`(report-result ,form ',form))
OK, rozumiem swój cel, ale mogę to zrobić za pomocą funkcji zamiast makra, na przykład:
(setf unevaluated.form '(= 2 (+ 2 3)))
(defun my-func (unevaluated.form)
(report-result (eval unevaluated.form) unevaluated.form))
- Jest to możliwe tylko dlatego, że dana makro jest zbyt proste ?
- Co więcej, czy Lisp Macro System jest tak potężny, względnie jego przeciwnicy ze względu na sam kod - jak struktury kontrolne, funkcje, itp. - jest reprezentowany jako LISTA?
Ta "złota reguła" jest głupia. Używaj makr wszędzie tam, gdzie uważasz, że są odpowiednie i zapomnij o wszystkich "regułach" uszkodzonych przez mózg. Co do Twojego przykładu, nie jest to prawie odpowiednik, ponieważ odkładasz kompilację do środowiska wykonawczego. Jeśli Twój formularz zawiera odniesienia do niektórych nazw o zasięgu lokalnym, po prostu nie zadziała. –
Sk, czy mógłbyś podać przykład dotyczący funkcji eval i nazwy o zasięgu lokalnym? – utxeee
'(niech ((x 2)) (eval '(+ x x)))' po prostu nie działałoby, OTOH gdyby ta forma '(+ x x)' została wygenerowana przez makro, byłoby naturalnie skompilowane. –