macros - 为什么这个 lisp 递归宏不起作用?

标签 macros lambda lisp scheme guile

我有宏 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/

相关文章:

c++ - 使用宏来专门化 std::swap

c - 如何编写 Makefile 以从一个源生成两个可执行文件?

c# - C# 中的 Lambda 示例

lambda - DrRacket : lambda anonymous function

vim 宏用 ',' 替换\n

rust - 有没有办法在宏中获取结构的字段名称?

amazon-web-services - 使用 Lambda 事件源映射进行 SQS 批处理

LISP 变量交换

lisp - Lisp 中的负无穷大

lisp - 在闭合多段线上绘制多边形