Re: [racket-users] read-eval-print-loop, #%top-interaction, and define
> On Sep 24, 2019, at 23:01, Jesse Alama wrote: > > The question is: we do we get the error with define if we know that step is > undefined? Shouldn't we learn, first, that step is undefined? The top level is hopeless. Unlike in a module, an unbound identifier at the top level is not a syntax error, as it might be a forward reference to a variable that is not yet defined (think mutually recursive functions). Therefore, the expander assumes that all unbound references at the top-level are variable references, and it expands (step e) like a function application applying the function `step` to the argument `e`. Function arguments are expressions, so when the expander goes to expand a definition in place of `e`, it raises an error. Obviously, the assumption that `step` is a forward variable reference was wrong here, as it was intended to refer to a macro. But the expander can’t know that, so it silently does the wrong thing. This behavior of the top-level seems like a misfeature—I’d be happy if mutually-recursive functions needed to be grouped with a `begin` at the top level—but it’s historically how Scheme programmers have expected the REPL to behave, and that behavior was much more important prior to the introduction of the modern Racket module system. Alexis -- 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/7D26C5BC-3010-40E7-9056-A6070CC22542%40gmail.com.
Re: [racket-users] read-eval-print-loop, #%top-interaction, and define
I managed to solve my problem, thanks to the suggestion that #%top-interaction should work as I expect (that is, allow define); your example shows that I was going down the wrong path in my thinking about the issue. What I found is a simple mistake: my expander wraps the define in another form, like this (whatever (assignment "a" 1)) But no binding for whatever is defined in the expander module. whatever is supposed to be just begin, but it wasn't even defined. What led me down the wrong path (wondering whether define works with #%top-interaction) was that I would have expected an unbound identifier error in this case, not something like "define not allowed in an expression context".This seems to clash with my mental model of evaluation & macros. If, in the example above, whatever is an unbound identifier, why are we even considering evaluating (assignment "a" 1)? To illustrate my puzzlement more concretely, I made a minimal example #lang. Let's call it #lang def. All you can do is assign numbers to variables. Example programs: (assignment "r" 5) (assignment "h" 9.5) Here's main.rkt for #lang def: #lang racket/base (module+ main (parameterize ([current-namespace (make-base-empty-namespace)]) (namespace-require 'def/expander) (read-eval-print-loop))) ; end of main.rkt And here's expander.rkt for #lang def: #lang racket/base ; To get a working REPL, define step (currently commented ; out) (provide assignment #%top-interaction #%datum) (require (for-syntax racket/base syntax/parse racket/syntax)) (define-syntax (assignment stx) (syntax-parse stx [(_ ident:string b:number) (with-syntax [(name (format-id #'ident "~a" (syntax->datum #'ident)))] #'(step (define name b)))])) #; (define-syntax (step stx) (syntax-parse stx [(_ s) #'s])) ; end of expander.rkt In a directory containing these two files, do $ raco pkg install -n def Then do $ racket main.rkt Now, in the REPL that fires up, do > (assignment "x" 6) You'll get the error I describe if step is undefined and not provided. If step is defined, assignment works as intended. The question is: we do we get the error with define if we know that step is undefined? Shouldn't we learn, first, that step is undefined? On Tuesday, September 24, 2019 at 4:23:10 PM UTC+2, Sam Tobin-Hochstadt wrote: > > It's fine to have `#%top-interaction` around a `define`: > > ``` > Welcome to Racket v7.4.0.10. > > (#%top-interaction . (define x 1)) > > x > 1 > ``` > > My guess is that your `#%top-interaction` is doing something that puts > it in an expression context. > > Sam > > On Tue, Sep 24, 2019 at 8:34 AM Jesse Alama wrote: > > > > I'm working on a REPL for a #lang in which one can make definitions. One > > writes > > > > $x := 5 > > > > and this gets parsed into an S-expression like > > > > (assignment "x" 5) > > > > The #lang is not based on S-expressions, but I believe that that's > > irrelevant (though I may be wrong). Naturally enough, I've set up the > > expander for my #lang so that S-expressions like the previous one get > > elaborated into a plain Racket define: > > > > (define x 5) > > > > The #lang works in DrRacket, and at the command line, too. The > > difficulty is the REPL, which is based on the same expander but a > > slightly modified reader. The problem shows up when one writes > > > > > $x := 5 > > > > in the REPL. There, I get > > > > define: not allowed in an expression context > > > > This makes sense to me because what's actually being evaluated in the > > REPL setting is > > > > (#%top-interaction assignment "a" 1) > > > > The define to which the assignment S-expression elaborates does indeed > > seem to be in an expression context. (Or, at least, it's not toplevel; > > the #%top-interaction makes sure of that.) > > > > Is there any way around this? Not being able to assign values to > > variables in the REPL is a blocker for me. I see a few options on the > > table for this issue: > > > > * Tweak current-eval (used by read-eval-print-loop). Doing this might > > open the door to bypassing #%top-interaction. What would that look > > like? Would one just destructure the given form to eval, checking > > whether it looks like a #%top-interaction, in which case throw it away > > and hand the rest to the "real" eval? > > > > * Change what assignment means. Thus, (assignment "a" 5) would no > > longer expand to (define a 5), but to something else, e.g., a set! or > > box-set! that modifies an environment that I maintain by hand. > > > > * Roll my own poor man's read-eval-print-loop. Of course, then I'd truly > > be in the driver's seat, but that option would clearly be a > > duplication of work the read-eval-print-loop is doing, and I really > > don't want to do that. > > > > Perhaps I'm missing s
Re: [racket-users] read-eval-print-loop, #%top-interaction, and define
It's fine to have `#%top-interaction` around a `define`: ``` Welcome to Racket v7.4.0.10. > (#%top-interaction . (define x 1)) > x 1 ``` My guess is that your `#%top-interaction` is doing something that puts it in an expression context. Sam On Tue, Sep 24, 2019 at 8:34 AM Jesse Alama wrote: > > I'm working on a REPL for a #lang in which one can make definitions. One > writes > > $x := 5 > > and this gets parsed into an S-expression like > > (assignment "x" 5) > > The #lang is not based on S-expressions, but I believe that that's > irrelevant (though I may be wrong). Naturally enough, I've set up the > expander for my #lang so that S-expressions like the previous one get > elaborated into a plain Racket define: > > (define x 5) > > The #lang works in DrRacket, and at the command line, too. The > difficulty is the REPL, which is based on the same expander but a > slightly modified reader. The problem shows up when one writes > > > $x := 5 > > in the REPL. There, I get > > define: not allowed in an expression context > > This makes sense to me because what's actually being evaluated in the > REPL setting is > > (#%top-interaction assignment "a" 1) > > The define to which the assignment S-expression elaborates does indeed > seem to be in an expression context. (Or, at least, it's not toplevel; > the #%top-interaction makes sure of that.) > > Is there any way around this? Not being able to assign values to > variables in the REPL is a blocker for me. I see a few options on the > table for this issue: > > * Tweak current-eval (used by read-eval-print-loop). Doing this might > open the door to bypassing #%top-interaction. What would that look > like? Would one just destructure the given form to eval, checking > whether it looks like a #%top-interaction, in which case throw it away > and hand the rest to the "real" eval? > > * Change what assignment means. Thus, (assignment "a" 5) would no > longer expand to (define a 5), but to something else, e.g., a set! or > box-set! that modifies an environment that I maintain by hand. > > * Roll my own poor man's read-eval-print-loop. Of course, then I'd truly > be in the driver's seat, but that option would clearly be a > duplication of work the read-eval-print-loop is doing, and I really > don't want to do that. > > Perhaps I'm missing something here. Any suggestions? > > -- > 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/7c946ee5-04e7-498f-8236-597d2d5ff39d%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%2Bb4SuxdPo8gsRktVYA8n7RdsJmDR4iuPN7qB%3D7eV0AetQ%40mail.gmail.com.
[racket-users] read-eval-print-loop, #%top-interaction, and define
I'm working on a REPL for a #lang in which one can make definitions. One writes $x := 5 and this gets parsed into an S-expression like (assignment "x" 5) The #lang is not based on S-expressions, but I believe that that's irrelevant (though I may be wrong). Naturally enough, I've set up the expander for my #lang so that S-expressions like the previous one get elaborated into a plain Racket define: (define x 5) The #lang works in DrRacket, and at the command line, too. The difficulty is the REPL, which is based on the same expander but a slightly modified reader. The problem shows up when one writes > $x := 5 in the REPL. There, I get define: not allowed in an expression context This makes sense to me because what's actually being evaluated in the REPL setting is (#%top-interaction assignment "a" 1) The define to which the assignment S-expression elaborates does indeed seem to be in an expression context. (Or, at least, it's not toplevel; the #%top-interaction makes sure of that.) Is there any way around this? Not being able to assign values to variables in the REPL is a blocker for me. I see a few options on the table for this issue: * Tweak current-eval (used by read-eval-print-loop). Doing this might open the door to bypassing #%top-interaction. What would that look like? Would one just destructure the given form to eval, checking whether it looks like a #%top-interaction, in which case throw it away and hand the rest to the "real" eval? * Change what assignment means. Thus, (assignment "a" 5) would no longer expand to (define a 5), but to something else, e.g., a set! or box-set! that modifies an environment that I maintain by hand. * Roll my own poor man's read-eval-print-loop. Of course, then I'd truly be in the driver's seat, but that option would clearly be a duplication of work the read-eval-print-loop is doing, and I really don't want to do that. Perhaps I'm missing something here. Any suggestions? -- 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/7c946ee5-04e7-498f-8236-597d2d5ff39d%40googlegroups.com.