ale*_*rov 9 macros common-lisp
曾几何时我正在玩宏并想出了这个:
(defmacro my-recursive-fact (n)
(if (= 0 n) '1
(let ((m (1- n)))
`(* ,n (my-recursive-fact ,m)))))
Run Code Online (Sandbox Code Playgroud)
它奏效了.
CL-USER> (my-recursive-fact 5)
120
Run Code Online (Sandbox Code Playgroud)
那么我认为如果我使用macroexpand以下方法扩展此宏,这可能是向学生展示递归示例的好方法:
CL-USER> (macroexpand '(my-recursive-fact 5))
(* 5 (MY-RECURSIVE-FACT 4))
T
Run Code Online (Sandbox Code Playgroud)
也就是说,在这种情况下macroexpand-1和之间没有区别macroexpand.我确信我在理解中缺少一些关键点macroexpand,HyperSpec对递归宏没有什么特别之处.
而且我仍然很想知道是否有办法将这种宏扩展到最后.
Lar*_*off 10
Slime有一个代码行走slime-macroexpand-all命令:http://common-lisp.net/project/slime/doc/html/Macro_002dexpansion.html
这可能没有文档和/或不受支持,但也许您可以从REPL调用它:
CL-USER> (swank-backend:macroexpand-all '(my-recursive-fact 5))
(* 5 (* 4 (* 3 (* 2 (* 1 1)))))
Run Code Online (Sandbox Code Playgroud)
MACROEXPAND采取一种形式并扩展它.它会多次执行,直到表单不再是宏形式.
在您的示例中,顶级调用my-recursive-fact是一个宏窗体.前面乘法的结果形式不是宏形式,因为*它不是宏.这是一个功能.表单有一个参数,它是一个宏形式.但MACROEXPAND不看那些.
如果要在所有级别上扩展代码,则需要使用代码walker.有些Lisps可以在IDE中直接访问它,比如Lispworks.
| 归档时间: |
|
| 查看次数: |
1154 次 |
| 最近记录: |