A Racket program is a set of modules. A module has a name, a language that gives its initial bindings, and a body of definitions and expressions. It imports what it needs with require and exports names with provide. Everything is lexically scoped: a module sees only what it requires or defines.
Declaring modules
| Form | Meaning |
|---|---|
#lang language … | the module that makes the rest of the file; shorthand for (module name language …) with the name taken from the file name |
(module id module-path form …) | declares a module. module-path names the language: the module whose exports give the initial bindings, and whose #%module-begin wraps the body |
(module* id module-path form …) | declares a submodule after the enclosing module; unlike a plain module, it can use the enclosing module's bindings. With #f in place of the language, the enclosing module's whole language and bindings are available |
(module+ id form …) | adds forms to a submodule that sees the enclosing module; several module+ forms of the same name are concatenated. It is the usual way to write main and test |
(#%module-begin form …) | the form that wraps a module body; a language can change what it does (to print expression results, or to add a timer). A module with no explicit one gets the language's |
(#%declare keyword …) | module-wide settings: #:cross-phase-persistent, #:empty-namespace, #:require=define, #:flatten-requires, #:unlimited-compile, #:unsafe and (#:realm id) |
A submodule is a module declared within another, written (submod "file.rkt" name) from outside, (submod "." name) relative to the enclosing module, and (submod ".." name) for a sibling. A submodule can be loaded without running the enclosing module, so the test and main submodules cost nothing when the file is required. main runs when the file is run with racket file.rkt; test is run by raco test; configure-runtime, reader and language-info are other submodule names that tools read (for example, the reader submodule of a language module is its #lang reader).
require
(require require-spec …) brings in names. It may appear at the top level of a module or the REPL, but not in an expression or internal-definition context. Each name can be imported only once (or twice from the same original definition), and a module cannot both import and define the same name.
| Specification | Imports |
|---|---|
| module-path | every export of the module |
(only-in spec id-or-[orig bind] …) | only the named exports, optionally renamed |
(except-in spec id …) | everything but the named exports |
(prefix-in prefix spec) | every name with a prefix added: (prefix-in s: racket/set) gives s:set-add |
(rename-in spec [orig bind] …) | some names under new names |
(combine-in spec …) | the union of the specifications |
(relative-in module-path spec …) | specifications whose relative paths are taken from another module's place |
(for-syntax spec …), (for-template spec …), (for-label spec …), (for-meta phase spec …) | import for use at another phase: compile time (for-syntax), the runtime of the module the compile-time code produces (for-template), documentation only, with no run-time effect (for-label), or a stated phase level number |
(only-meta-in phase spec …), (only-space-in space spec …), (for-space space spec …) | restrict an import to one phase or one binding space |
(multi-in …), (matching-identifiers-in …), (filtered-in …), (subtract-in …), (path-up …) | derived specifications from racket/require: several paths at once, names by regular expression, names changed by a procedure, a set difference, a path that searches the directories above |
Module paths
| Path | Names |
|---|---|
racket/list (an identifier) | shorthand for (lib "…") with the same characters (an identifier must not contain a dot). racket/list is the file list.rkt of the racket collection: .rkt is added when the last element has no suffix. A single element with no slash and no suffix, such as slideshow, is a collection, and its main.rkt is meant |
"x.rkt", "../x.rkt", "dir/x.rkt" | a file relative to the requiring file. The string is always a Unix-style path: / separates, .. is the parent, no leading or trailing slash, only ASCII letters and digits and - + _ . / %. A .ss suffix is read as .rkt |
(lib "x/y.rkt") | a collection path written out |
(file "/abs/path.rkt") | a file by its operating-system path |
(planet …) | a package of the old PLaneT system, now mostly replaced by raco pkg packages |
(submod path name …), (submod "." name), (submod ".." name) | a submodule |
'id | a module declared interactively or a submodule of the current module |
provide
(provide provide-spec …) makes names visible to other modules. The names must be defined or imported in the module.
| Specification | Exports |
|---|---|
id | that binding under the same name |
(all-defined-out) | every name the module defines (not the ones it imports) |
(all-from-out module-path …) | every name imported from those modules |
(rename-out [orig export] …) | names under different external names |
(except-out spec spec …) | the first specification without the later ones |
(prefix-out prefix spec) | names with a prefix |
(struct-out id) | a structure type's constructor, predicate, accessors and mutators (not its supertype's) |
(combine-out spec …) | the union of specifications |
(protect-out spec …) | exports that code with less trust cannot use through a protected import |
(for-syntax spec …), (for-template …), (for-label …), (for-meta phase spec …), (for-space space spec …) | exports at another phase or binding space |
(contract-out [id contract] …) | exports with a contract attached at the module boundary (racket/contract) |
(matching-identifiers-out …), (filtered-out …) | derived specifications of racket/provide: names that match a regular expression, or renamed by a procedure |
#lang racket/base
(require racket/list ; everything
(only-in racket/string string-join) ; one name
(prefix-in set: racket/set) ; set:set-add
(for-syntax racket/base) ; for macros
"util.rkt" ; a file beside this one
(submod "util.rkt" test-helpers)) ; a submodule of it
(provide (struct-out point)
(contract-out [dist (-> point? point? real?)])
(rename-out [internal-name public-name]))
(struct point (x y))
(define (dist a b) (sqrt (+ (sqr (- (point-x a) (point-x b))) (sqr (- (point-y a) (point-y b))))))
(define (internal-name) 42)
Phases and instantiation
Racket separates the compile-time work of macros from the run-time work of the program by phases: phase 0 is run time, phase 1 is the code of macros, phase 2 the code of macros that make macros, and so on, with for-syntax moving an import up by one. A module is instantiated at a phase when its definitions are run there, and visited when only its macros are made available. A for-label import binds names for documentation and tools only; it does not instantiate or visit the module. The Racket Reference chapter on the module evaluation model describes instantiation, visiting and lazy compile-time instantiation in full; this page does not.
The module language also matters: #lang racket/base gives a small core and starts quickly, #lang racket adds most of the library, and a module may choose any other language, including its own. See The #lang family.
Namespaces and eval
A namespace is the top-level environment that eval, the REPL and dynamic-require use. (dynamic-require module-path 'name) loads a module and returns an export, or runs it with (void) as the name. (namespace-require module-path) imports into a namespace, make-base-namespace and make-base-empty-namespace make fresh ones, and (module->namespace …) gives access to a module's inside. lazy-require delays loading a module until a function from it is called.
Not described
Known, not yet covered
- Reference: the module name resolver and the collection search path (
current-module-name-resolver,current-library-collection-paths, links files), the compiled-load handler,#:cross-phase-persistentconstraints, the details of binding spaces (for-spaceandonly-space-inare only named), and the PLaneT forms (planet) were not described.racket/requireandracket/providespecifications are named from the Reference's syntax chapter and not described. - Reference: the
configure-runtimeandlanguage-infosubmodule roles come from memory of the Guide and were not checked in the downloaded text.
See also
- Macros – what
for-syntaximports are for - Packages and raco – collections, packages and how to install them
- Scheme: libraries and modules – the Scheme library systems