宏调用宏在Gambit Scheme中给出了“未定义的变量”

时间:2017-05-07 19:50:40

标签: macros scheme gambit

在Gambit Scheme中,如果编译文件,我似乎无法在另一个宏的定义中调用宏。这是一个人为的例子:

import '../assets/data/test';

但是,如果我在解释器中加载带有;;;; example.scm (define-macro (w/gensyms gs body) `(let ,(map (lambda (g) `(,g (gensym ',g))) gs) ,body)) (define-macro (compose-macro f g) (w/gensyms (x) `(lambda (,x) (,f (,g ,x))))) (define my-cadr (lambda (x) ((compose-macro car cdr) x))) ;; $ gsc example.scm ;; *** ERROR IN #<procedure #2> -- Unbound variable: w/gensyms 特殊表单的文件,则可以正常工作

(include ...)

有谁知道这里发生了什么?我可以说服Gambit让我在编译文件中定义另一个宏时使用w / gensyms吗?

2 个答案:

答案 0 :(得分:0)

这很可能与阶段有关。

试试这个:

w/gensyms放入文件a.scm中,并将compose-macro放入导入a.scm的文件b.scm中。

答案 1 :(得分:0)

这是一个阶段性问题。您希望w / gensyms的定义在后续宏的主体中可用。这可以通过for语法宏来实现,该宏强制在语法扩展时评估宏定义:

(define-macro (for-syntax . body)
  (eval `(begin ,@body))
  `(begin))

(for-syntax
 (define-macro (w/gensyms gs body)
   `(let ,(map (lambda (g) `(,g (gensym ',g)))
               gs)
      ,body)))

如果您希望宏在其他宏定义和非宏定义代码中都可用,则可以使用它:

(define-macro (for-syntax . body)
  (eval `(begin ,@body))
  `(begin ,@body))

对于这个具体的例子,由于你在一个地方使用宏,你可以这样做:

(define-macro (compose-macro f g)

   (define-macro (w/gensyms gs body)
     `(let ,(map (lambda (g) `(,g (gensym ',g)))
                 gs)
        ,body))

  (w/gensyms (x)
    `(lambda (,x) (,f (,g ,x)))))

解决阶段性问题的相关方法是将w / gensyms和其他宏的定义放在文件“macros.scm”中并执行:

(define-macro (compose-macro f g)

  (include "macros.scm")

  (w/gensyms (x)
    `(lambda (,x) (,f (,g ,x)))))