2013-08-14 10 views
5

Per dare un esempio semplice:Esiste un modo per definire una variabile macro in fase di compilazione (tempo di espansione) in Racket o in qualsiasi altro Schema?

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

Tale che dato:

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

il seguente dovrebbero essere tutti restituiscono #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) 

v'è alcuna vera caratteristica racket che fa quello define-macro-variable dovrebbe fare nell'esempio sopra?

EDIT:

Ho trovato un work-around:

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

ma io preferirei una soluzione che non richiede tutte le macro che utilizzano le variabili macro di essere in una sola espressione.

risposta

8

Si desidera define-for-syntax (in racchetta).

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

produce tutto vero.