有没有办法在Racket或任何其他Scheme中定义编译时(扩展时)宏变量?

时间:2013-08-14 17:47:10

标签: macros scheme racket define-syntax

举一个简单的例子:

(define-macro-variable _iota 0) ; define-macro-variable does not really exist

(define-syntax (iota stx)
  (syntax-case stx ()
    ((iota)
     (let ((i _iota))
       (set! _iota (+ i 1))
       #`#,i))))

如此:

(define zero (iota))
(define one-two-three (list (iota) (iota) (iota)))
(define (four) (iota))

以下所有内容都应评估为#t

(equal? zero 0)
(equal? one-two-three '(1 2 3)) ; possibly in a different order
(equal? (four) 4)
(equal? (four) 4)
(equal? (four) 4)

是否有任何真正的球拍功能可以执行上述示例中define-macro-variable应该执行的操作?

编辑:

我找到了解决办法:

(define-syntaxes (macro-names ...)
  (let (macro-vars-and-vals ...)
    (values macro-bodies-that-nead-the-macro-vars ...)))

但我更喜欢一种解决方案,它不要求所有使用宏变量的宏都在一个表达式中。

1 个答案:

答案 0 :(得分:9)

你想要define-for-syntax(在Racket中)。

(define-for-syntax _iota 0)

(define-syntax (iota stx)
  (syntax-case stx ()
    ((iota)
     (let ((i _iota))
       (set! _iota (+ i 1))
       #`#,i))))

(define zero (iota))
(define one-two-three (list (iota) (iota) (iota)))
(define (four) (iota))

(equal? zero 0)
(equal? one-two-three '(1 2 3))
(equal? (four) 4)
(equal? (four) 4)
(equal? (four) 4)

产生所有真实。