# Running and Creating Executables While developing programs, many Racket programmers use the DrRacket programming environment. To run a program without the development environment, use `racket` \(for console-based programs\) or `gracket` \(for GUI programs\). This chapter mainly explains how to run `racket` and `gracket`. 1 Running `racket` and `gracket` 1.1 Interactive Mode 1.2 Module Mode 1.3 Load Mode 2 Scripts 2.1 Unix Scripts 2.2 Windows Batch Files 3 Creating Stand-Alone Executables ## 1. Running `racket` and `gracket` The `gracket` executable is the same as `racket`, but with small adjustments to behave as a GUI application rather than a console application. For example, `gracket` by default runs in interactive mode with a GUI window instead of a console prompt. GUI applications can be run with plain `racket`, however. Depending on command-line arguments, `racket` or `gracket` runs in interactive mode, module mode, or load mode. ### 1.1. Interactive Mode When `racket` is run with no command-line arguments \(other than confguration options, like `-j`\), then it starts a REPL with a `> ` prompt: `Welcome to Racket v7.1.0.6.` `>` > For enhancing your REPL experience, see `xrepl`; for information on GNU > Readline support, see `readline`. To initialize the REPL’s environment, `racket` first requires the `racket/init` module, which provides all of `racket`, and also installs `pretty-print` for display results. Finally, `racket` loads the file reported by `(find-system-path 'init-file)`, if it exists, before starting the REPL. If any command-line arguments are provided \(other than configuration options\), add `-i` or `--repl` to re-enable the REPL. For example,   `racket -e '(display "hi\n")' -i` displays “hi” on start-up, but still presents a REPL. If module-requiring flags appear before `-i`/`--repl`, they cancel the automatic requiring of `racket/init`. This behavior can be used to initialize the REPL’s environment with a different language. For example,   `racket -l racket/base -i` starts a REPL using a much smaller initial language \(that loads much faster\). Beware that most modules do not provide the basic syntax of Racket, including function-call syntax and `require`. For example,   `racket -l racket/date -i` produces a REPL that fails for every expression, because `racket/date` provides only a few functions, and not the `#%top-interaction` and `#%app` bindings that are needed to evaluate top-level function calls in the REPL. If a module-requiring flag appears after `-i`/`--repl` instead of before it, then the module is required after `racket/init` to augment the initial environment. For example,   `racket -i -l racket/date` starts a useful REPL with `racket/date` available in addition to the exports of `racket`. ### 1.2. Module Mode If a file argument is supplied to `racket` before any command-line switch \(other than configuration options\), then the file is required as a module, and \(unless `-i`/`--repl` is specified\), no REPL is started. For example,   `racket hello.rkt` requires the `"hello.rkt"` module and then exits. Any argument after the file name, flag or otherwise, is preserved as a command-line argument for use by the required module via `current-command-line-arguments`. If command-line flags are used, then the `-u` or `--require-script` flag can be used to explicitly require a file as a module. The `-t` or `--require` flag is similar, except that additional command-line flags are processed by `racket`, instead of preserved for the required module. For example,   `racket -t hello.rkt -t goodbye.rkt` requires the `"hello.rkt"` module, then requires the `"goodbye.rkt"` module, and then exits. The `-l` or `--lib` flag is similar to `-t`/`--require`, but it requires a module using a `lib` module path instead of a file path. For example,   `racket -l raco` is the same as running the `raco` executable with no arguments, since the `raco` module is the executable’s main module. Note that if you wanted to pass command-line flags to `raco` above, you would need to protect the flags with a `--`, so that `racket` doesn’t try to parse them itself:   `racket -l raco -- --help` ### 1.3. Load Mode The `-f` or `--load` flag supports `load`ing top-level expressions in a file directly, as opposed to expressions within a module file. This evaluation is like starting a REPL and typing the expressions directly, except that the results are not printed. For example,   `racket -f hi.rkts` `load`s `"hi.rkts"` and exits. Note that load mode is generally a bad idea, for the reasons explained in \[missing\]; using module mode is typically better. The `-e` or `--eval` flag accepts an expression to evaluate directly. Unlike file loading, the result of the expression is printed, as in a REPL. For example,   `racket -e '(current-seconds)'` prints the number of seconds since January 1, 1970. For file loading and expression evaluation, the top-level environment is created in the same way for interactive mode: `racket/init` is required unless another module is specified first. For example,   `racket -l racket/base -e '(current-seconds)'` likely runs faster, because it initializes the environment for evaluation using the smaller `racket/base` language, instead of `racket/init`. ## 2. Scripts Racket files can be turned into executable scripts on Unix and Mac OS. On Windows, a compatibility layer like Cygwin support the same kind of scripts, or scripts can be implemented as batch files. ### 2.1. Unix Scripts In a Unix environment \(including Linux and Mac OS\), a Racket file can be turned into an executable script using the shell’s `#!` convention. The first two characters of the file must be `#!`; the next character must be either a space or `/`, and the remainder of the first line must be a command to execute the script. For some platforms, the total length of the first line is restricted to 32 characters, and sometimes the space is required. > Use `#lang` `racket/base` instead of `#lang` `racket` to produce scripts > with a faster startup time. The simplest script format uses an absolute path to a `racket` executable followed by a module declaration. For example, if `racket` is installed in `"/usr/local/bin"`, then a file containing the following text acts as a “hello world” script: `#! /usr/local/bin/racket` `#lang racket/base` `"Hello, world!"` In particular, if the above is put into a file `"hello"` and the file is made executable \(e.g., with `chmod a+x hello`\), then typing `./hello` at the shell prompt produces the output `"Hello, world!"`. The above script works because the operating system automatically puts the path to the script as the argument to the program started by the `#!` line, and because `racket` treats a single non-flag argument as a file containing a module to run. Instead of specifying a complete path to the `racket` executable, a popular alternative is to require that `racket` is in the user’s command path, and then “trampoline” using `/usr/bin/env`: `#! /usr/bin/env racket` `#lang racket/base` `"Hello, world!"` In either case, command-line arguments to a script are available via `current-command-line-arguments`: `#! /usr/bin/env racket` `#lang racket/base` `(printf "Given arguments: ~s\n"` `(current-command-line-arguments))` If the name of the script is needed, it is available via `(find-system-path 'run-file)`, instead of via `(current-command-line-arguments)`. Usually, the best way to handle command-line arguments is to parse them using the `command-line` form provided by `racket`. The `command-line` form extracts command-line arguments from `(current-command-line-arguments)` by default: `#! /usr/bin/env racket` `#lang racket` `(define verbose? (make-parameter #f))` `(define greeting` `(command-line` `#:once-each` `[("-v") "Verbose mode" (verbose? #t)]` `#:args` `(str) str))` `(printf "~a~a\n"` `greeting` `(if (verbose?) " to you, too!" ""))` Try running the above script with the `--help` flag to see what command-line arguments are allowed by the script. An even more general trampoline uses `/bin/sh` plus some lines that are comments in one language and expressions in the other. This trampoline is more complicated, but it provides more control over command-line arguments to `racket`: `#! /bin/sh` `#|` `exec racket -e '(printf "Running...\n")' -u "$0" ${1+"$@"}` `|#` `#lang racket/base` `(printf "The above line of output had been produced via\n")` `(printf "a use of the `-e' flag.\n")` `(printf "Given arguments: ~s\n"` `(current-command-line-arguments))` Note that `#!` starts a line comment in Racket, and `#|`...`|#` forms a block comment. Meanwhile, `#` also starts a shell-script comment, while `exec racket` aborts the shell script to start `racket`. That way, the script file turns out to be valid input to both `/bin/sh` and `racket`. ### 2.2. Windows Batch Files A similar trick can be used to write Racket code in Windows `.bat` batch files: `; @echo off` `; Racket.exe "%~f0" %*` `; exit /b` `#lang racket/base` `"Hello, world!"` ## 3. Creating Stand-Alone Executables For information on creating and distributing executables, see \[missing\] and \[missing\] in \[missing\].