28

I have been trying to launch a racket program from the commandline (via 'racket') but have not been having success. According to the documentation (here http://docs.racket-lang.org/reference/running-sa.html#%28part._mz-cmdline%29) passing -f followed by a file should evaluate that file. However, I can't seem to get this to work. As a test, I made the following file:

;test.rkt
#lang racket
(define a 1)

Then, running it in racket (supposedly loading the file) and attempting to recall the value of a:

racket -f test.rkt -i
Welcome to Racket v5.1.1.
> a
reference to undefined identifier: a

My end goal is to be able to launch a different program from a shell script using the --main option combined with loading the definitions with -f to start up execution, just have become a bit baffled since I can't seem to get this trivial bit working.

Michael McGuinness
  • 283
  • 1
  • 3
  • 4

2 Answers2

33

Removing the #lang line works, but it means that your code is no longer a module, which makes it a pretty bad idea. To start racket on a given module file, all you need is to just run racket on the file, nothing else is needed. For example, put this in test.rkt:

#lang racket/base
(printf "Hi\n")

and just run it with racket test.rkt. If you want to have command-line flags, you can use (current-command-line-arguments) to get a vector of additional command-line arguments, but there's also the racket/cmdline library that makes it much easier to have standard kinds of flag processing. Here's an example for that:

#lang racket/base

(require racket/cmdline)

(define excitedness "")
(define mode "Hi")
(command-line
  #:multi
  [("-e" "--excited") "add excitedness levels"
   (set! excitedness (string-append excitedness "!"))]
  #:once-each
  [("-b" "--bye") "turn on \"bye\" mode"
   (set! mode "Bye")])

(printf "~a~a\n" mode excitedness)

and you can now run it with racket test.rkt <flags>. See also the Racket Guide's section on scripts for making your test.rkt even easier to run.

Finally, there is the --main approach that you've seen -- to use that, your module needs to provide a main function that receives all the command-line flags as arguments. For example:

#lang racket/base
(require racket/string)
(provide main)
(define (main . xs)
  (printf "You gave me ~s flags: ~a\n"
          (length xs) (string-join xs ", ")))

and to run it:

racket -t /tmp/y -m -- foo bar baz

The flag breakdown is: -t requires your module, -m causes racket to run your main function, and -- means that the following flags are all passed to your program. You can combine the flags like so:

racket -tm- /tmp/y foo bar baz

and that would be something that you'd usually put in your script trampoline as described in that guide section.

And, of course, this is all described in great details in the reference manual.

Eli Barzilay
  • 29,301
  • 3
  • 67
  • 110
  • Hi, I'm confused, when I do `racket file.rkt` it is evaluated, but I want REPL so I do `racket file.rkt -i` but no REPL?! – Vladimir Keleshev Aug 12 '11 at 21:28
  • 7
    If you want a REPL inside a module, start racket as usual, and then use [`enter!`](http://docs.racket-lang.org/reference/enter.html#%28form._%28%28lib._racket/enter..rkt%29._enter!%29%29). Alternatively, use a nightly build with the new `xrepl` facility which gives you a more convenient `,enter` command. – Eli Barzilay Aug 12 '11 at 21:33
  • Right now I use `enter!`, but I wanted to make a short-cut in Vim to evaluate and run REPL. Any idea? – Vladimir Keleshev Aug 12 '11 at 21:38
  • I don't know much about vim -- but isn't the idea similar to vi, where you start the editor, write some code, then quit and run stuff in the shell? For this mode of work, the new [XREPL](http://pre.racket-lang.org/docs/html/xrepl/) thing that I mentioned is useful -- you get an `,e` command that simply runs your `$EDITOR` on a given file, defaulting to the module you've entered into. – Eli Barzilay Aug 12 '11 at 22:49
  • Yea, that is ideal to me, I am downloading the nightly build (although it was hard to find on racket-lang.org. I wonder wat was the usual workflow before XREPL? In vim you can execute shell commands (and interact with them) without exiting the editor. So you can set up it similar to DrRacket (Well, now that there is XREPL). I guess there should have been some workarounds before... Or maybe everyone is happy with DrRacket and don't need another editor. – Vladimir Keleshev Aug 13 '11 at 00:34
4

Remove the #lang racket header from your file:

;test.rkt
(define a 1)
yarian
  • 5,922
  • 3
  • 34
  • 48
  • Thank you! Figured it must be something simple - I'm so used to working in drracket it never occurred to me that could cause an issue. – Michael McGuinness Jun 17 '11 at 01:34
  • I'd like to note that I do not delete my answer as the TL;DR version of Eli's below. But you should *really* be paying attention to him. – yarian Nov 06 '12 at 02:01
  • It's easy to do this in the shell without modifying the file: `racket -i -f <(tail -n +2 test.rkt)` – ankh-morpork Sep 20 '19 at 12:59