在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吗?
答案 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)))))