方案编译器如何确定宏扩展期间哪些函数可用?
我的意思是这样的低级机制,比如语法大小写,你不仅可以生成模式替换,还可以调用一些函数,至少在挡泥板部分
我的意思是,我需要在宏扩展过程中使用普通函数。 E. g。:
(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)的评估。
答案 0 :(得分:1)
每个Scheme编译器都确定宏扩展引用的函数。在你的情况下,'let-syntax'的编译将导致编译器确定'two'是免费的(语法超出'let-syntax'范围内)。应用宏时,将解析对“两次”函数的自由引用。
不同的Scheme编译器可能在不同的时间执行自由值解析。您可以通过将“两次”定义为:
来见证这一点(define twice
(begin (display 'bound')
(lambda (x) (* 2 x))))
[在你的情况下,使用let-syntax很难注意到。我建议使用define-syntax然后再使用'(mac 4')。有了这个,一些编译器(guile)会在编译define-syntax时打印'bound';当'(mac 4)'被扩展时,其他人(ikarus)将打印'bound'。]
答案 1 :(得分:0)
这取决于您使用的宏系统。其中一些系统允许您在扩展期间调用常规方案功能。例如,Explicit Renaming Macros允许您这样做:
(define-syntax swap!
(er-macro-transformer
(lambda (form rename compare?)
...
`(let ((tmp ,x))
(set! ,x ,y)
(set! ,y tmp)))))
也就是说,您可以使用的宏系统将取决于您使用的是什么方案。