Hi Matthew, Thank you for the quick reply!
I tried the example you gave for my first question and it resulted in an error. I have the following as `module-that-defines-fib`: #lang racket (provide fib) (define fib "fib") And this is the error that I got (using Racket 7.6): ; application: not a procedure; ; expected a procedure that can be applied to arguments ; given: "fib" ; [,bt for context] I think this is because `(define-values (x) ...)` expands `...` without the top-level-bind-scope, even when expand-context-to-parsed? is #t (according to expander/expand/top.rkt). Is this a bug? Related to your answer to my second question, `define-syntaxes` similarly does not add the top-level-bind-scope when expanding `...`. Does this mean that even for `define-syntaxes`, `...` won't use the top-level-bind-scope binding(s) after all? A little bit off-topic, in the definition of define-values (in expander/expand/top.rkt), there is `(define-match m s ...)`, but for define-syntaxes it is `(define-match m disarmed-s ...)`. Is this difference significant? Or does define-match not care whether `s` or `disarmed-s` is used? Thanks, Yongming On Saturday, March 21, 2020 at 9:25:01 AM UTC-4, Matthew Flatt wrote: > > At Sat, 21 Mar 2020 00:00:07 -0700 (PDT), Yongming Shen wrote: > > First, in the source file expander/expand/bind-top.rkt, there is a > comment > > that says "When compiling `(define-values (x) ...)` at the top level, > > we'd like to bind `x` so that a reference in the "..." will point back > to > > the definition, as opposed to being whatever `x` was before." Isn't this > > the exact opposite of what (define-values (x) ...) should do? > > Here's an example scenario that the current rule is meant to cover: > > > (require module-that-defines-fib) > > > fib ; refers to binding from `module-that-defines-fib` > > > (define (fib n) > (if (< n 2) > 1 > (+ (fib (- n 1)) (fib (- n 2))))) ; refers to this definition > > > (fib 27) ; => 514229 > > If a programmer usually expects the `fib`s in the definition's `...` > region here to refer to the new definition, not to the imported > binding, then the implemented rule is the right one. If programmers > expect that `fib`s in the `...` to refer to the imported binding, then > I'd agree with you. But I think the former is more often the case. > > Neither rule is obviously right, and if we make the example more > complicated with more macros involved, I'm pretty sure there's no way > to implement either rule consistently: the top level is hopeless. The > case of a single recursive function seems common enough that we've > picked a rule and implementation to make it work. > > > Second, ignoring the comment mentioned above, but still consider > > `(define-values (x) ...)`. It appears that the binding of `x` to `...` > with > > the top-level-bind-scope is only used by `(#%top . x)` (either explicit > or > > implicit). The only exception seems to be in contexts where neither `x` > nor > > #%top are binded, in which case `x`, not wrapped by #%top, also uses > that > > binding. The case of `(#%top . x)` is confusing because even without the > > top-level-bind-scope binding of `x`, `(#%top . x)` can still locate > > `(define-values (x) ...)`, otherwise mutually recursive functions won't > > work at the top level. As for the exception case, it seems rare enough > that > > it can be ignored. So my question is, what's benefit does the > > top-level-bind-scope bring? > > Just to restate (to make sure I understand), you're pointing out that > an unbound identifier is treated the same as a binding using the > top-level scope (i.e., both refer to a top-level variable) --- so why > bother with the top-level scope? > > Although the result is the same for variable references, it's not the > same for macro bindings or for imported bindings. And, then, there's no > way to predict in advance that an identifier will be used as a variable > and omit the top-level scope in that case. > > Stepping back a little, it may not be the right design choice to treat > an unbound identifier as a reference to a top-level variable. But some > sort of default is necessary to support the traditional top level. And > treating unbound identifiers this was avoids a[nother] special > treatment of top-level scopes, where an unbound variable could be > treated as a variable reference only if it has a top-level scope. > > Really, the only consistent approach that I know is to not have an > interactive top level, but that's not an attractive option. > > > Matthew > > -- 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/a6f90504-7260-41ea-b8d7-0311c7ef7a9f%40googlegroups.com.

