Is there any way to define a compile-time (expansion-time) macro variable in Racket or any other Scheme?
define-syntax, macros, racket, scheme
Solution
You want `define-for-syntax` (in 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)
produces all true.
Problem
To give a simple example: ``` (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)))) ``` Such that given: ``` (define zero (iota)) (define one-two-three (list (iota) (iota) (iota))) (define (four) (iota)) ``` the following should all evaluate to `#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) ``` Is there any real racket feature that does what `define-macro-variable` is supposed to do in the example above? EDIT: I found a work-around: ``` (define-syntaxes (macro-names ...) (let (macro-vars-and-vals ...) (values macro-bodies-that-nead-the-macro-vars ...))) ``` but I would prefer a solution that does not require all the macros that use the macro variables to be in one expression.