我有宏 let--(就像 let* 使用 lambda 一样)在诡计中:
(define (let-make-lambdas pairs body)
(if (null? pairs)
`((lambda () ,@body))
`((lambda (,(caar pairs))
,(let-make-lambdas (cdr pairs) body))
,(cadar pairs))))
(define-macro (let-- pairs . body)
(let-make-lambdas pairs body))
当我使用外部函数进行代码生成时它工作正常,但下面的代码(with 只是一个宏)不起作用:
(define-macro (let-- pairs . body)
(if (null? pairs)
`((lambda () ,@body))
`((lambda (,(caar pairs))
,(let-- (cdr pairs) body))
,(cadar pairs))))
为什么?
最佳答案
第二,你不想
,(let-- (cdr pairs) body)
而是
(let-- ,(cdr pairs) ,@body)
也就是你的直接宏实现应该是
(define-macro (let-- pairs . body)
(if (null? pairs)
`((lambda () ,@body))
`((lambda (,(caar pairs))
(let-- ,(cdr pairs) ,@body))
,(cadar pairs))))
您不想在宏扩展时评估内部 (let-- ...)
;它是应该生成的源的一部分。 (当然,它很快就会被宏扩展。)为了突出这一点,考虑一个宏,它变成了
(plus a b c d)
进入
(+ a (+ b (+ c d)))
它需要像这样展开
(+ ,(car args) (plus ,@(cdr args)))
但不是
(+ ,(car args) ,(plus (cdr args)))
因为后者会尝试计算 (plus '(b c d))
,这是行不通的。
关于macros - 为什么这个 lisp 递归宏不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19549583/