This is indeed an issue where "the top-level is hopeless" is the problem [1].
However, there's a better work-around. You can write `(define-syntaxes (name.r ...) (values))` to forward-declare all those names, and then the subsequent definitions will work correctly. Sam [1] https://lists.racket-lang.org/users/archive/2005-November/010350.html is a good short description of the problem here. On Fri, Jun 25, 2021 at 5:34 PM Greg Rosenblatt <[email protected]> wrote: > > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/racket-users/cd8675e8-95d0-4552-badc-d4ec7a430109n%40googlegroups.com. -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2BYeXuQP4yErTQe3g7aCSM7iOLfkJpFXDHodZQ29zf_agg%40mail.gmail.com.

