Command-line Racket: Run xrepl commands using -e flag in interactive terminal - racket

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")'

Related

Racket Not Loading Module File

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

Pass Expression as arguments to Clojure REPL

I have been learning Clojure and lately I have been using the REPL as a comand line calculator, my 'workflow' would be greatly improved if it were possible to pass arguments to the Clojure REPL and get the output, does anyone know how to do that?
Clarification: For example I would like to execute lein "(+ 2 2)" and have it return 4
~  lein "(+ 2 2)"
'(+ 2 2)' is not a task. See 'lein help'.
grenchman creates a repl, and each command line invocation gets a result from that repl, this is likely what you want.
lein (Leiningen) is the wrong tool for this, other than starting up a REPL. If you really want a command line interface to some Clojure program, that's possible too, but requires you to compile it to a jar and execute it, cf. this article on building CLI clojure apps.
Anything you def is available at the REPL.
=> (def ten 10)
...
=> (defn fact [n] (apply * (range 1 (inc n))))
...
=> (fact ten)
3628800
=>
# as bash variable
{ echo "$clj-expressions"; cat - ; } | lein repl
# as file
{ cat ./script.clj; cat - ; } | lein repl
Lucky for us, lein repl is just a plain-old unix process
The idea here is to send your commands to the repl's stdin but ensure that the current terminal's stdin is connected afterwards.
Thanks to Jonathan Leffler for this one. His answer here solved this.
To collect output, you can always spit something out as part of the script you run.
This is exactly how REPL works - you write some expression and press Enter, got expression result back.
→ lein repl
nREPL server started on port 59650 on host 127.0.0.1
REPL-y 0.3.0
Clojure 1.5.1
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (+ 42 42)
84
user=>

Racket: execute file and stay in interactive mode

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

Racket: How do I make the -s option to "raco test" work?

According to the docs for raco test, there is a -s option that will test submodules with names other than test. But I can't seem to make this work. If I have the following file:
;; example.rkt
#lang racket
(module foo racket
(display "Hi, I'm running!"))
Then trying to pass foo as the submodule name to raco test results in:
$ raco test example.rkt -s foo
testing example.rkt
test: Given path #<path:-s> does not exist
context...:
/Applications/Racket v5.3.3/collects/compiler/commands/test.rkt: [running body]
/Applications/Racket v5.3.3/collects/raco/raco.rkt: [running body]
/Applications/Racket v5.3.3/collects/raco/main.rkt: [running body]
If I just use the name test:
;; example.rkt
#lang racket
(module test racket
(display "Hi, I'm running!"))
Then, raco test works fine:
$ raco test example.rkt
testing example.rkt
Hi, I'm running!
But I really want to have several test suites that I selectively run with various calls to raco test.
Try passing the flag before the filename. Like this:
$ raco test -s foo example.rkt

How do I get the program name in 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.