我正在编写一个递归 Lisp 宏,取一个数字n并评估主体n次(来自 ANSI Lisp 的练习)。我尝试了两种方法——让宏在其扩展中调用自身,以及让宏扩展为本地递归函数。两者都不像我想要的那样工作。
这是第一个——它有一个堆栈溢出,但是当我使用macroexpand-1 查看它的扩展时,它对我来说似乎很好。
(defmacro n-times (n &rest body)
(let ((i (gensym)))
`(let ((,i ,n))
(if (zerop ,i) nil
(progn
,@body
(n-times (- ,i 1) ,@body))))))
这是第二个 - 它出错,“未定义的函数 #xxxx 调用参数(z)”其中 #xxxx 是 gensym 的名称,z 比我调用它的数字小 1。我认为我同时使用 gensyms 和 flet 的方式存在问题,但我不确定如何正确执行此操作。
(defmacro n-times (n &rest body)
(let ((g (gensym)))
`(flet ((,g (x)
(if (zerop x) nil
(progn
,@body
(,g (- x 1))))))
(,g ,n))))