I've encountered an identifier binding order issue that only manifests in the REPL. My current workaround is to use forward definitions followed by set!s. I've heard rumors that the top-level is hopeless, but I'd like to try and make this work without unnecessary workarounds, if possible.
To demonstrate the issue, I've defined a syntax transformer that binds temporary names to procedures, and defines wrapper syntax transformers for referencing these procedures. This syntax works fine within a module, or other non-top-level definition context. But when used at the top-level, I get an unbound identifier error as the first procedure body is being expanded. The first procedure references the second via the wrapper. ;; issue.rkt #lang racket/base (provide issue-syntax) (require (for-syntax racket/base)) (define-syntax (issue-syntax stx) (syntax-case stx () ((_ ((name param ...) body ...) ...) (with-syntax (((name.r ...) (generate-temporaries #'(name ...)))) #'(begin (define-syntax (name stx) (syntax-case stx () ((_ . args) #'(name.r . args)) (_ #'name.r))) ... (define name.r (lambda (param ...) body ...)) ...))))) ;; eof > racket Welcome to Racket v8.0 [cs]. > (require "issue.rkt") > (let () (issue-syntax ((foo x) (bar x 1 2)) ; note the reference to bar ((bar a b c) `(bar: ,a ,b ,c))) (foo 'is-the-top-level-hopeless?)) (bar: is-the-top-level-hopeless? 1 2) > (issue-syntax ((foo x) (bar x 1 2)) ; note the reference to bar ((bar a b c) `(bar: ,a ,b ,c))) ; bar4: unbound identifier; ; also, no #%top syntax transformer is bound ; in: bar4 ; [,bt for context] > ,bt ; bar4: unbound identifier; ; also, no #%top syntax transformer is bound ; in: bar4 ; context...: ; /Applications/Racket v8.0/share/pkgs/xrepl-lib/xrepl/xrepl.rkt:1493:0 ; /Applications/Racket v8.0/collects/racket/repl.rkt:11:26 I can work around this issue by altering issue-syntax to forward-define names before using set! to initialize them: (define-syntax (issue-syntax stx) (syntax-case stx () ((_ ((name param ...) body ...) ...) (with-syntax (((name.r ...) (generate-temporaries #'(name ...)))) #'(begin (define-syntax (name stx) (syntax-case stx () ((_ . args) #'(name.r . args)) (_ #'name.r))) ... (define name.r #f) ... ; forward definitions (set! name.r (lambda (param ...) body ...)) ...))))) Is there a better alternative? -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/cd8675e8-95d0-4552-badc-d4ec7a430109n%40googlegroups.com.