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 <greg.we...@gmail.com> 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 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.

-- 
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/CAK%3DHD%2BYeXuQP4yErTQe3g7aCSM7iOLfkJpFXDHodZQ29zf_agg%40mail.gmail.com.

Reply via email to