2013-08-14 53 views
5

Để cung cấp một ví dụ đơn giản:Có cách nào để xác định một biến vĩ mô (mở rộng thời gian) biến biên dịch trong Racket hoặc bất kỳ Đề án nào khác không?

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

như vậy mà đưa ra:

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

sau tất cả nên đánh giá để #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) 

Có bất kỳ tính năng vợt thực sự mà làm gì define-macro-variable có nghĩa vụ phải làm trong ví dụ trên?

EDIT:

Tôi tìm thấy một công việc xung quanh:

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

nhưng tôi muốn một giải pháp mà không đòi hỏi tất cả các macro có sử dụng các biến vĩ mô được trong một biểu thức.

Trả lời

8

Bạn muốn define-for-syntax (trong vợt).

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

tạo ra tất cả sự thật.