How do I set the meta-language in the Racket REPL? - racket

I have a program that uses the at-exp meta-language:
#lang at-exp racket
(define v '#f{str})
(displayln v)
I want to manually type it line-by-line into the Racket REPL. Unfortunately, #lang at-exp racket is not valid in the REPL:
$ racket
Welcome to Racket v6.11.
> #lang at-exp racket
; readline-input:1:0: read: #lang not enabled in the current context [,bt for
; context]
; at-exp: undefined;
; cannot reference undefined identifier
; [,bt for context]
; racket: undefined;
; cannot reference undefined identifier
; [,bt for context]
>
How do I set the meta-language in the Racket REPL?

For the beginners who have ended up here, the short answer is no. The #lang shorthand should only be used in files. If you want to run your example program in the REPL, you could load it using this command.
racket --repl --eval '(enter! (file "your-file.rkt"))'
The more detailed answer is that the #lang shorthand gets re-written behind the scenes into module form.
So for example something like this...
#lang racket
(define v "Hello!")
(displayln v))
Is re-written to what you see below and you could copy and paste this into the repl and then require the module, e.g. in the repl type...
> (module the-hello-module racket
(define v "Hello!")
(displayln v))
> (require 'the-hello-module)
Hello!
But from what I can tell, that re-write is dependent on the languages you're using, so the rewrite is probably not something you want to do manually and I don't think the at-exp metalanguage is something you would be add manually to module form.

I don't know why they're different, but the REPL inside DrRacket can use the #lang shorthand:
Unlike the command-line REPL, the DrRacket REPL adopts the language spec­i­fied by the #lang line at the top of the defi­n­i­tions panel. DrRacket also uses the REPL itself to print output from the program.
https://beautifulracket.com/explainer/repl.html#a_Rv5YS
So if you have #lang at-exp racket/base in the definitions panel and click "Run" the bottom REPL panel will show Language: at-exp racket/base, etc., and this will work:
> #string-append{this is a test}
"this is a test"
That page also says:
More intri­cate REPL hacking is possible. For instance, the REPL can be config­ured to use a custom reader (other than Racket’s default S-expres­sion reader).
https://beautifulracket.com/basic-3/the-repl.html
However, the steps described there are much more involved than I care to get into. I don't know what DrRacket is doing in the background to make #lang at-exp work.

Related

Why is "swindle" different in the racket interpreter than in drracket?

Can someone explain the difference between using drracket with swindle (any of the versions) and firing up the interpreter as: racket -I swindle
Many expressions evaluate the same in both environments, but some don't. For example:
(let-syntax ((let* (syntax-rules () ((let* a b) "You used let*")))) (let* 3 4))
... evaluates to "You used let*" in every scheme-based language I tried in drracket. However, it fails in the interpreter brought up by "racket -I swindle" on the command line with the error
; readline-input:1:20: syntax-rules: unbound identifier;
; also, no #%app syntax transformer is bound in the transformer phase
; at: syntax-rules
; in: (syntax-rules () ((let* a b) "You used let*"))
; [,bt for context]
Your example uses syntax-rules at phase 1 (aka the "for-syntax phase", aka the "transformer phase"), but it appears that the swindle module (unlike racket/base and racket) does not provide any bindings for-syntax. (It looks like swindle uses an old technique to provide phase-1 bindings that works for modules written in the swindle language but not for a REPL started with racket -l swindle.)
One workaround is to evaluate
(require (for-syntax racket/base))
before evaluating your example, and then your example should work as you expect.

Why does (require (for-syntax 'm)) execute expressions in the required module 3 times in DrRacket?

I don't know how to explain the following behavior in DrRacket's interactions window. I think the output should be only one "hello", since the module m should be instantiated once in this case. But actually "hello" is printed 3 times.
> (module m racket
(printf "hello\n"))
> (module n racket
(require (for-syntax 'm)))
hello
hello
hello
>
The same behavior also exists if I write this example in DrRacket's definitions window and run it.
#lang racket
(module m racket
(printf "hello\n"))
(module n racket
(require (for-syntax (submod ".." m))))
hello
hello
hello
>
This example is a simplified version of one from Racket's guide (https://docs.racket-lang.org/guide/macro-module.html) -- the first example in 16.3.2. The behavior shown in that document
is intuitive (printing the string one time), but when I execute that code in DrRacket's interactions window, it also prints the string 3 times.
I'm using DrRacket version 7.7.
See also https://github.com/greghendershott/racket-mode/issues/379 and https://github.com/racket/drracket/issues/278.
The latter in particular indicates that one of the extra ones is from errortrace instrumentation, which is on by default in DrRacket.

Why can't I customize the application of a struct-id construction function?

I would like to build a custom language in Racket that requires redefining the implicit form #%app. However, using the macro stepper I noticed that unlike regular "proc-id" function application, struct-id application does not get replaced with the custom #%app form. Why is this the case?
My guess is that what you are seeing in the macro stepper is a result of the fact that (unless you specify otherwise with keyword options) struct binds the struct name to a macro to communicate static information about the struct type, which is used by match, shared, struct-out, and other macros. When used as an expression, this macro expands to the constructor function, which is bound to an otherwise-inaccessible name. If that doesn't seem to explain what you're seeing, perhaps you could give a code example.
In any case, if you disable macro hiding, you will see that direct application of the constructor function does use the correct #%app form. For example, this program:
#lang racket
(module language racket
(provide (rename-out [my-app #%app])
(except-out (all-from-out racket)
#%app))
(define-syntax-rule (my-app rator rand ...)
(let ()
(print-app-form '(rator rand ...))
(rator rand ...)))
(define (print-app-form quoted)
(printf "; ~a\n" quoted)))
(module main (submod ".." language)
(struct bag (contents)
#:transparent)
(define groceries
'(oranges milk salsa))
(bag groceries))
prints the following output, where bag1 is an artifact of #%app being expanded after the bag macro:
; (bag1 groceries)
(bag '(oranges milk salsa))

How to re-export #%module-begin etc from scribble/text?

I want a language like scribble/text but with some additional functions offered. This is what I've tried:
#lang racket/base
(require scribble/text)
(provide (all-from-out scribble/text)
hello)
(define (hello name)
(format "Hello ~a!" name))
When I try to run a module written in this language, I get a message saying that there is no #%module-begin binding in the module's language.
I assume that scribble/text has a binding for #%module-begin, else how does it work when I use it as a #lang?
Maybe scribble/text knows that I am importing it using 'require' rather than as a #lang, and so I don't automatically get the #% macros? If that's the case, then how would I get them and re-export them?
Or is something else happening here?
The language for #lang scribble/text and the library for (require scribble/text) are different modules. The library version doesn't provide #%module-begin or the other bindings from racket:
When scribble/text is used via require instead of #lang, then .... it does not include the bindings of racket/base ....
The module-language #lang scribble/text actually uses is scribble/text/lang. So you can fix your module-language like this:
#lang racket/base
(require scribble/text/lang)
(provide (all-from-out scribble/text/lang)
hello)
(define (hello name)
(format "Hello ~a!" name))
However, the module scribble/text/lang is undocumented, so use at your own risk.

Undefined ADT in r5rs

I'm writing an ADT in r5rs and I'm using DrRacket. I put #lang r5rs at the top of my file and chose Determine Language from Source from DrRacket, but it tells me my ADT is undefined. I'm using DrRacket version 6.0. It's the first time I've had this and can't understand what I'm doing wrong.
My ADT
#lang r5rs
(#%require "queue.rkt") ;A required file
(#%provide (all-defined))
(define (my-ADT)
(let ((val1 '())
(val2 '()))
(define (foo) ...)
(define (bar) ...)
(define (dispatch msg)
(case msg
((foo) foo)
((bar) bar)
(else "Unknown message")))
dispatch))
When I try to create an instance of my-ADT I get the following output: my-ADT: undefined; cannot reference an identifier before its definition
When I remove #lang r5rs from the top and choose R5RS as language in DrRacket, it seems to work. But then my queue.rkt file still has #lang r5rs at the top and Determine Language from Source. When I remote #lang r5rs and choose R5RS as language in that file also, I get the following in the my-ADT file:
default-load-handler: expected a `module' declaration
found: something else
in: #<path:/Users/path/path/path/queue.rkt>
The error
my-ADT: undefined; cannot reference an identifier before its definition
normally indicates that the function my-ADT was used before it was defined.
That is, one must place all definitions on top of the file and place the expressions below.
Your example above has no uses of my-ADT so if you get this error, the problem might be in "queue.rkt". Can you run "queue.rkt" without errors?