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.

Reply via email to