Macros 宏调用宏时给出;未定义变量";花招

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

在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 (,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使用一个称为黑洞的模块系统: