Macros 宏调用宏时给出;未定义变量";花招
在Gambit方案中,如果编译文件,我似乎无法在另一个宏的定义中调用宏。下面是一个人为的例子:Macros 宏调用宏时给出;未定义变量";花招,macros,scheme,gambit,Macros,Scheme,Gambit,在Gambit方案中,如果编译文件,我似乎无法在另一个宏的定义中调用宏。下面是一个人为的例子: ;;;; 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
;;;; 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
有人知道这里发生了什么吗?我能否说服Gambit允许我在编译文件中定义另一个宏时使用w/gensyms?这很可能与阶段有关 试试这个:
将
w/gensyms
放入文件a.scm中,并将compose macro
放入导入a.scm的文件b.scm中 这很可能与阶段有关
试试这个:
将
w/gensyms
放入文件a.scm中,并将compose macro
放入导入a.scm的文件b.scm中 这是一个分阶段问题。您希望在后续宏的主体中提供w/gensyms的定义。这可以通过for syntax宏实现,该宏在语法扩展时强制计算宏定义:
(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”中,并执行以下操作:
这是一个分阶段的问题。您希望在后续宏的主体中提供w/gensyms的定义。这可以通过for syntax宏实现,该宏在语法扩展时强制计算宏定义:
(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宏我知道我不应该使用define宏导入如何?根据gambit手册,我需要使用
include
来拼接宏定义。如果我理解正确,gambit使用一个名为黑洞的模块系统:如何导入?根据gambit手册,我需要使用include
在宏定义中拼接。如果我理解正确,gambit使用一个称为黑洞的模块系统: