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 racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/a6f90504-7260-41ea-b8d7-0311c7ef7a9f%40googlegroups.com.