You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/quad/qtest/mds/running.md

268 lines
10 KiB
Markdown

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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 REPLs 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 REPLs 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 executables 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` doesnt
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 shells `#!` 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 users 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\].