Hi. I have been trying to create a macro that communicates without using mutation, but I'm having problems with communicating across multiple modules.
I have three files: macro.rkt: #lang racket (provide start add) (require (for-syntax syntax/parse racket/match racket/syntax)) (begin-for-syntax ;; (thing stx-lst next-id) ;; stx-lst : Syntax ; will be quoted ;; next-id : Identifier ; points to the next identifier, which is or will be the next thing ;; if the next thing exists, then this one is old (struct thing (stx-lst next-id) #:transparent) ;; get-thing : Identifier -> thing (define (get-thing id) (follow-next-things (syntax-local-value id))) ;; follow-next-things : thing -> thing (define (follow-next-things v) (match v [(thing _ next-id) (define v* (syntax-local-value (syntax-local-introduce next-id) (λ () #f))) (cond [v* (follow-next-things v*)] [else v])]))) (define-syntax start (syntax-parser [(start id) #:with next (generate-temporary #'id) #'(define-syntax id (thing #'() #'next))])) (define-syntax add (syntax-parser [(add id new-stx) #:do [(match-define (thing stx next-id) (get-thing #'id))] #:with (old-stx ...) (syntax-local-introduce stx) #:with next (syntax-local-introduce next-id) #:with next-next (generate-temporary #'id) (printf "macro.rkt add\n next: ~v\n" #'next) #'(begin (define-syntax next (thing #'(old-stx ... new-stx) #'next-next)) '(old-stx ... new-stx))])) test1.rkt: #lang racket (provide id) (require "macro.rkt") (start id) (add id a) ; '(a) (add id b) ; '(a b) test2.rkt: #lang racket (require "macro.rkt" "test1.rkt") (add id c) ; this works fine, produces '(a b c) when run ;(add id d) ; module: duplicate definition for identifier If I uncomment the last line of test2.rkt, it produces that duplicate definition error. I'm guessing that the second use of add in test2.rkt isn't picking up the next-id definition put there by the first use of add in test2.rkt. When I run test1.rkt in DrRacket it prints out: macro.rkt add next: .#<syntax id1> macro.rkt add next: .#<syntax id2> '(a) '(a b) The first 4 lines were printed out by the add macro at compile time, and the last 2 are the run time results. When I run test2.rkt in DrRacket it prints out: macro.rkt add next: .#<syntax id3> '(a) '(a b) '(a b c) But then if I uncomment the last line: macro.rkt add next: .#<syntax id3> macro.rkt add next: .#<syntax id3> module: duplicate definition for identifier in: id3 With this at the bottom: module: duplicate definition for identifier at: id3 in: (define-syntaxes (id3) (thing (syntax (a b d)) (syntax id2))) The message at the bottom shows that the (add id d) isn't picking up the next-id definition put there by the (add id c), so that it puts out (a b d) instead of (a b c d), and tries to define the same next-id that the previous (add id c) already defined. What's happening here? I know about the separate compilation guarantee, but don't think that could be the problem, since it works perfectly when add is used only once in test2.rkt. Alex Knauth -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.