簡體   English   中英

為什么這個Lisp遞歸宏不起作用?

[英]Why this lisp recursive macro doesn't work?

我在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))))

您不想在宏擴展時評估內部(let-- ...) 它是應生成的源代碼的一部分。 (當然,稍后將對其進行宏平移。)要突出顯示這一點,請考慮將

(plus a b c d)

進入

(+ a (+ b (+ c d)))

它需要像

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

但不是

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

因為后者會嘗試評估(plus '(bcd)) ,這將無法正常工作。

我認為約書亞為您解決了問題。 我只想指出, Scheme標准使用syntax-rulessyntax-case syntax-rules可能像這樣:

;; 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)

這是一個有效的Common 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

我想對應的Scheme版本是

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM