2013-08-14 15 views
5

Aby dać prosty przykład:Czy istnieje sposób definiowania zmiennej makro (czasu kompilacji) w Racket lub na jakimkolwiek innym schemacie?

(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)))) 

taka, że ​​udzielona:

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

następujące powinny ocenić na #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) 

Czy istnieje funkcja prawdziwa rakieta, która co robi define-macro-variable ma zrobić w powyższym przykładzie?

EDIT:

znalazłem obejście:

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

ale wolałbym rozwiązanie, które nie wymaga wszystkie makra, które używają zmiennych makro, aby być w jednej wypowiedzi.

Odpowiedz

8

Chcesz define-for-syntax (w rakiecie).

(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) 

produkuje wszystko prawda.