如何在scheme中定义编译时可用函数?

时间:2013-01-28 08:05:38

标签: scheme

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

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

编辑:

我的意思是,我需要在宏扩展过程中使用普通函数。 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)的评估。

2 个答案:

答案 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)))))

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