2013-08-14 2 views
5

Чтобы дать простой пример:Есть ли способ определить макрокоманду времени компиляции (время расширения) в Racket или любой другой схеме?

(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 должен сделать в примере выше?

EDIT:

Я нашел работу вокруг:

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

, но я предпочел бы решение, которое не требует всех макросов, которые используют макропеременные быть в одном выражении.

ответ

8

Вы хотите 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) 

все производит.

 Смежные вопросы

  • Нет связанных вопросов^_^