Macros 为什么这个lisp递归宏不';不行?

Macros 为什么这个lisp递归宏不';不行?,macros,lambda,lisp,scheme,guile,Macros,Lambda,Lisp,Scheme,Guile,我在guile中使用了宏let--(比如let*使用lambdas): (define (let-make-lambdas pairs body) (if (null? pairs) `((lambda () ,@body)) `((lambda (,(caar pairs)) ,(let-make-lambdas (cdr pairs) body)) ,(cadar pairs)))) (define-mac

我在guile中使用了宏let--(比如let*使用lambdas):

(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))
当我使用外部函数生成代码时,它可以正常工作,但是下面的代码(只是宏)不起作用:

(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))))
您不希望在宏展开时计算内部
(让--…)
;它是应该生成的源代码的一部分。(当然,它很快就会被宏文件化)。
(plus a b c d)
进入

它需要像这样扩张

(+ ,(car args) (plus ,@(cdr args)))
但不是

(+ ,(car args) ,(plus (cdr args)))

因为后者将尝试计算
(plus'(bcd))
,这将不起作用。

在第二种情况下,您不希望

,(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))))
您不希望在宏展开时计算内部
(让--…)
;它是应该生成的源代码的一部分。(当然,它很快就会被宏文件化)。
(plus a b c d)
进入

它需要像这样扩张

(+ ,(car args) (plus ,@(cdr args)))
但不是

(+ ,(car args) ,(plus (cdr args)))

因为后者将尝试计算
(plus'(b c d))
,这将不起作用。

这里是一个通用的Lisp版本:

(defmacro let1-- (pairs . body)
  (if (null pairs)
      `((lambda () ,@body))
      `((lambda (,(caar pairs))
         (let-- ,(cdr pairs) . ,body))
         ,(cadar pairs))))
> (macroexpand '(let1-- ((a 1) (b 2)) (+ b a)))
((LAMBDA (A) (LET-- ((B 2)) (+ B A))) 1) ;
T
> (let1-- ((a 1) (b 2)) (+ b a))
3
我想对应的方案版本是

(define-macro (let-- pairs . body)
    (if (null? pairs)
        `((lambda () ,@body))
        `((lambda (,(caar pairs))
            (let-- ,(cdr pairs) . ,body))
          ,(cadar pairs))))

以下是一个通用Lisp版本:

(defmacro let1-- (pairs . body)
  (if (null pairs)
      `((lambda () ,@body))
      `((lambda (,(caar pairs))
         (let-- ,(cdr pairs) . ,body))
         ,(cadar pairs))))
> (macroexpand '(let1-- ((a 1) (b 2)) (+ b a)))
((LAMBDA (A) (LET-- ((B 2)) (+ B A))) 1) ;
T
> (let1-- ((a 1) (b 2)) (+ b a))
3
我想对应的方案版本是

(define-macro (let-- pairs . body)
    (if (null? pairs)
        `((lambda () ,@body))
        `((lambda (,(caar pairs))
            (let-- ,(cdr pairs) . ,body))
          ,(cadar pairs))))

我想约书亚找到了你问题的答案。我只想指出,
Scheme
标准使用
语法规则
语法大小写
。在
语法规则中可能是这样的:

;; make let* with lambdas
(define-syntax let--
  (syntax-rules ()
    ;; base case, last pair
    ((let-- ((key1 value1)) . body) 
     ((lambda (key1) . body ) value1))

    ;; default case, several
    ((let-- ((key1 value1) . kv-pairs) . body) 
     ((lambda (key1) (let-- kv-pairs . body)) value1))))

(let-- ((a 'a) (b a) (c b)) (list a b c)) ; ==> (a a a)

我想约书亚找到了你问题的答案。我只想指出,
Scheme
标准使用
语法规则
语法大小写
。在
语法规则中可能是这样的:

;; make let* with lambdas
(define-syntax let--
  (syntax-rules ()
    ;; base case, last pair
    ((let-- ((key1 value1)) . body) 
     ((lambda (key1) . body ) value1))

    ;; default case, several
    ((let-- ((key1 value1) . kv-pairs) . body) 
     ((lambda (key1) (let-- kv-pairs . body)) value1))))

(let-- ((a 'a) (b a) (c b)) (list a b c)) ; ==> (a a a)

忘记带括号了吗p宏调用似乎与其定义不一致:点丢失。@sds
用于定义Common Lisp中的
&rest
列表。在第一种情况下,jcubic定义了一个函数来执行代码扩展,而宏确实包含了
@JoshuaTaylor:我的意思是,宏的调用必须有一个
(如我的回答中所示)或一个
@
(如你的回答中所示)@sds哦,我明白你的意思了。定义中的
(let--…)
可能是
(let--(cdr pairs).body)
。对(只要其他问题得到解决)。对不起,我误解了。忘了带括号了吗p宏调用似乎与其定义不一致:点丢失。@sds
用于定义Common Lisp中的
&rest
列表。在第一种情况下,jcubic定义了一个函数来执行代码扩展,而宏确实包含了
@JoshuaTaylor:我的意思是,宏的调用必须有一个
(如我的回答中所示)或一个
@
(如你的回答中所示)@sds哦,我明白你的意思了。定义中的
(let--…)
可能是
(let--(cdr pairs).body)
。对(只要其他问题得到解决)。对不起,我误解了。我更喜欢支持它们的lisp宏和scheme实现,但还是要感谢你的回答。我更喜欢支持它们的lisp宏和scheme实现,但还是要感谢你的回答。