1

方案编译器如何确定在宏扩展期间哪些函数可用?

我的意思是这样的低级机制,比如语法案例,你不仅可以生成模式替换,还可以调用一些函数,至少在 fender 部分

编辑:

我的意思是,我需要在宏扩展过程中使用普通函数。例如:

(define (twice a)
  (declare 'compile-time)
  (* 2 a))
(let-syntax ((mac (lambda (x)
                    (syntax-case x ()
                      ((_ n) (syntax (display (unsyntax (twice n)))))))))
   (mac 4))

其中 n 已知是一个数字,并且 (两次 n) 的评估发生在扩展过程中。

4

2 回答 2

1

每个 Scheme 编译器都会确定宏扩展引用的函数。在您的情况下,“let-syntax”的编译将导致编译器确定“两次”是免费的(在“let-syntax”中的语法超出范围)。应用宏时,对“两次”函数的自由引用将被解决。

不同的 Scheme 编译器可能在不同的时间执行自由值解析。您可以通过将“两次”定义为:

(define twice
  (begin (display 'bound')
         (lambda (x) (* 2 x))))

[在您的情况下,使用 let-syntax 很难注意到。我建议先定义语法,然后再使用 '(mac 4')。这样,一些编译器(guile)将在编译定义语法时打印“绑定”;当 '(mac 4)' 展开时,其他 (ikarus) 将打印 'bound'。]

于 2013-02-25T16:32:41.167 回答
0

这取决于您使用的宏系统。其中一些系统允许您在扩展期间调用常规方案函数。例如,显式重命名宏允许您这样做:

(define-syntax swap!
  (er-macro-transformer
    (lambda (form rename compare?)
      ...
      `(let ((tmp ,x))
         (set! ,x ,y)
         (set! ,y tmp)))))

也就是说,您可用的宏系统将取决于您使用的方案。

于 2013-01-28T18:15:32.130 回答