I am trying to load my racket file so that I can test it interactively similar to what DrRacket allows.
test.rkt:
#lang racket
(define blah 1)
I am trying to run it using this command:
racket -it test.rkt
Which works and I get the usual output:
Welcome to Racket v6.6.
>
But when I try to get the value of blah it doesnt work:
> blah
blah: undefined;
cannot reference undefined identifier
context...:
/usr/share/racket/collects/racket/private/misc.rkt:88:7
How can I run this program interactively?
The easiest way is probably to use xrepl: (require xrepl) (or add the require to your .racketrc), then use the ,enter command to “move inside” the module:
$ racket
Welcome to Racket v6.6.0.4.
> ,enter test.rkt
> blah
1
You are very close. You just need to provide blah so that it can be used from the repl.
#lang racket
(provide blah)
(define blah 1)
And then when you run it with racket -it test.rkt, you get:
Welcome to Racket v6.6.0.4.
> blah
1
Related
I'd like to take an existing language, say, htdp/isl, and add a few definitions that aren't included by default. I can (require blah) at the top of every file, but I want to just be able to write #lang my-modified-isl at the top, and get those definitions along with the rest of the language. It's okay if this only works for languages that are "close" to Racket (i.e., have a boring reader).
In Racket, a #lang is basically just any module that provides #%module-begin (and optionally a reader/parser). As an example, you can check out my SML package (no relation to Standard ML), which is almost vanilla Racket, but a few custom tweaks to make it really good for describing data (like YAML).
Let's say you want to make a version of vanilla Racket, but that includes the function standard-fish, and lacks a divide (/) function. You could make your file:
#lang racket ; custom-racket.rkt
(require pict)
(provide (except-out (all-from-out racket) /)
standard-fish)
And now you can use s-exp to put your new language in the #lang line:
#lang s-exp "custom-racket.rkt"
(standard-fish) ; A fish
(/ 10 2) ; Error, `/` undefined
(Note that if you want to get rid of S-Expressions entirely and replace the reader, you would use #lang reader instead.)
Finally, you can package your file into a custom Racket package to use directly. Rename custom-racket.rkt from above to custom-racket/main.rkt, add an info.rkt file, and install the package:
$ mkdir custom-racket
$ cd custom-racket
$ vim main.rkt
#lang racket ; custom-racket.rkt
(require pict)
(provide (except-out (all-from-out racket) /)
standard-fish)
(module reader syntax/module-reader
custom-lang)
$ vim info.rkt
#lang info
(define collection "custom-racket")
$ raco pkg install
And now you can use custom-racket directly in the #lang line:
#lang custom-racket
(standard-fish) ; A fish
(/ 10 2) ; Error, `/` undefined
I found an answer that mentions entering a racket file using XREPL as shown below:
$ racket
Welcome to Racket vX.X.X.
-> ,en foo.rkt
42
"foo.rkt">
What would be the way to type in the first line while calling racket from the command-line itself?
Something like:
$ racket -ie ',en foo.rkt'
however, the above line outputs the following error:
Welcome to Racket v7.2.
string::1: unquote: not in quasiquote
in: (unquote en)
location...:
string::1
context...:
do-raise-syntax-error
expand-capturing-lifts
temp118_0
temp91_0
compile15
temp85_0
>
This works in Racket 8.5.
racket -i -e '(enter! "foo.rkt")'
I write a read-syntax function but ı get this error. my read-syntax function is this:
(define (read-syntax path port)
(for([line (port->lines port)])
(parse-line line)))
The error is this:
Module Language: only a module expression is allowed, either
#lang <language-name>
or
(module <name> <language> ...)
Each racket file is a module.
The file must start with defining the module.
The easy starting way is to have
#lang racket
as the first line of your module.
Description of this is in the Racket Guide https://docs.racket-lang.org/guide/intro.html
Is there a way from a command line to run Racket file and stay in the interactive mode afterwards?
E.g. same in Python it would be:
python -i <file.py>
Assuming a foo.rkt that's this:
#lang racket
(provide x)
(define x 42)
(define y 4242)
Then you can use -i to specify interactive mode (= REPL), together with -t to require the file:
$ racket -it foo.rkt
Welcome to Racket vX.X.X.
> x
42
> y
y: undefined; ...
> (exit)
Note that y is not bound since it's in the module and not provided out. More likely you want a REPL that is "inside" the foo module, which can be done using enter! to go into the module's namespace, either in the REPL:
$ racket
> (enter! "foo.rkt")
> x
42
> y
4242
> (exit)
or on the command-line, using -e (and also -i to request a REPL):
$ racket -i -e '(enter! "foo.rkt")'
Welcome to Racket vX.X.X.
> x
42
> (+ x 12)
54
> (exit)
xrepl
If you do this a lot, you'll probably like xrepl. In your ~/.racketrc simply add:
(require xrepl)
Now the example becomes:
$ racket
Welcome to Racket vX.X.X.
-> ,en foo.rkt
42
"foo.rkt"> x
42
"foo.rkt"> (+ x 12)
54
"foo.rkt"> ,ex
Aside from ,en, XREPL has a bunch of goodness -- like the prompt indication of the module you're currently in, as well as a bunch of other useful commands:
$ racket
Welcome to Racket vX.X.X.
-> ,h
; Available commands:
; help (h ?): display available commands
; exit (quit ex): exit racket
; cd: change the current directory
; pwd: display the current directory
; shell (sh ls cp mv rm md rd git svn): run a shell command
; edit (e): edit files in your $EDITOR
; drracket (dr drr): edit files in DrRacket
; apropos (ap): look for a binding
; describe (desc id): describe a (bound) identifier
; doc: browse the racket documentation
; require (req r): require a module
; require-reloadable (reqr rr): require a module, make it reloadable
; enter (en): require a module and go into its namespace
; toplevel (top): go back to the toplevel
; load (ld): load a file
; backtrace (bt): see a backtrace of the last exception
; time: time an expression
; trace (tr): trace a function
; untrace (untr): untrace a function
; errortrace (errt inst): errortrace instrumentation control
; profile (prof): profiler control
; execution-counts: execution counts
; coverage (cover): coverage information via a sandbox
; switch-namespace (switch): switch to a different repl namespace
; syntax (stx st): set syntax object to inspect, and control it
; check-requires (ckreq): check the `require's of a module
; log: control log output
; install!: install xrepl in your Racket init file
Emacs
However if you're an Emacs user you might prefer using something like:
Geiser
Quack minor mode for scheme-mode
racket-mode (shameless self-promotion)
If you are using Visual Studio Code as an editor, you may want to use the "Code Runner extension"
make sure it's installed from the vs code marketplace
then enter Preferences: Open Settings (JSON) and past the following:
"code-runner.executorMap": {
"racket": "(exit); racket -i -e '(enter! \"$fileName\")'",
},
You will be able to run directly your file by clicking the Run Code icon or by pressing Ctrl+Alt+N
NB: the same manouvre goes for "scheme" since it's interpreted by racket as well, however putting #lang racket in the top of your file is necessary
It can be done with
racket -if <file.rkt>
However it will not work as expected if the file starts with
#lang racket
I would like to programmatically detect the program name within Racket code. This can be done in Chicken Scheme with:
#!/bin/sh
#|
exec csi -ss $0 ${1+"$#"}
exit
|#
(define (main)
(display (format "Program: ~a\n" (program-name)))
(exit))
(if (not (equal? (program-name) "csi"))
(main))
How could I emulate this in Racket?
Is this what you want?
(find-system-path 'run-file)
See also racket/cmdline for how to parse the commandline.
http://docs.racket-lang.org/reference/Command-Line_Parsing.html
Note: for this particular pattern of execution, to have a library module that can also be run as a main, use a submodule named main. See Main and Test Submodules, which shows how to do this.