3.1 Modules: module, module*, ...
The module Form in The Racket Guide introduces module.
syntax
(module id module-path form ...)
For a module-like form that works in definition contexts other than the top level or a module body, there’s define-package, but using a separate module or submodule is usually better.
The module-path form must be as for require, and it supplies the initial bindings for the body forms. That is, it is treated like a (require module-path) prefix before the forms, except that the bindings introduced by module-path can be shadowed by definitions and requires in the module body forms.
If a single form is provided, then it is partially expanded in a module-begin context. If the expansion leads to #%plain-module-begin, then the body of the #%plain-module-begin is the body of the module. If partial expansion leads to any other primitive form, then the form is wrapped with #%module-begin using the lexical context of the module body; this identifier must be bound by the initial module-path import, and its expansion must produce a #%plain-module-begin to supply the module body. Finally, if multiple forms are provided, they are wrapped with #%module-begin, as in the case where a single form does not expand to #%plain-module-begin.
After such wrapping, if any, and before any expansion, an 'enclosing-module-name property is attached to the #%module-begin syntax object (see Syntax Object Properties); the property’s value is a symbol corresponding to id.
Each form is partially expanded (see Partial Expansion) in a module context. Further action depends on the shape of the form:
If it is a begin form, the sub-forms are flattened out into the module’s body and immediately processed in place of the begin.
If it is a define-syntaxes form, then the right-hand side is evaluated (in phase 1), and the binding is immediately installed for further partial expansion within the module. Evaluation of the right-hand side is parameterized to set current-namespace as in let-syntax.
If it is a begin-for-syntax form, then the body is expanded (in phase 1) and evaluated. Expansion within a begin-for-syntax form proceeds with the same partial-expansion process as for a module body, but in a higher phase, and saving all #%provide forms for all phases until the end of the module’s expansion. Evaluation of the body is parameterized to set current-namespace as in let-syntax.
If the form is a #%require form, bindings are introduced immediately, and the imported modules are instantiated or visited as appropriate.
If the form is a #%provide form, then it is recorded for processing after the rest of the body.
If the form is a define-values form, then the binding is installed immediately, but the right-hand expression is not expanded further.
If the form is a module form, then it is immediately expanded and declared for the extent of the current top-level enclosing module’s expansion.
If the form is a module* form, then it is not expanded further.
Similarly, if the form is an expression, it is not expanded further.
After all forms have been partially expanded this way, then the remaining expression forms (including those on the right-hand side of a definition) are expanded in an expression context. After all expression forms, #%provide forms are processed in the order in which they appear (independent of phase) in the expanded module. Finally, all module* forms are expanded in order, so that each becomes available for use by subsequent module* forms; the enclosing module itself is also available for use by module* submodules.
The scope of all imported identifiers covers the entire module body, except for nested module and module* forms (assuming a non-#f module-path in the latter case). The scope of any identifier defined within the module body similarly covers the entire module body except for such nested module and module* forms. The ordering of syntax definitions does not affect the scope of the syntax names; a transformer for A can produce expressions containing B, while the transformer for B produces expressions containing A, regardless of the order of declarations for A and B. However, a syntactic form that produces syntax definitions must be defined before it is used.
No identifier can be imported or defined more than once at any
phase level within a single module, except that a definition
via define-values or define-syntaxes can shadow an
import via #%require—
The evaluation of a module form does not evaluate the expressions in the body of the module (except sometimes for redeclarations; see Module Redeclarations). Evaluation merely declares a module, whose full name depends both on id or (current-module-declare-name).
A module body is executed only when the module is explicitly instantiated via require or dynamic-require. On invocation, imported modules are instantiated in the order in which they are required into the module (although earlier instantiations or transitive requires can trigger the instantiation of a module before its order within a given module). Then, expressions and definitions are evaluated in order as they appear within the module. Each evaluation of an expression or definition is wrapped with a continuation prompt (see call-with-continuation-prompt) for the default prompt tag and using a prompt handler that re-aborts and propagates its argument to the next enclosing prompt. Each evaluation of a definition is followed, outside of the prompt, by a check that each of the definition’s variables has a value; if the portion of the prompt-delimited continuation that installs values is skipped, then the exn:fail:contract:variable? exception is raised.
Portions of a module body at higher phase levels are delimited similarly to run-time portions. For example, portions of a module within begin-for-syntax are delimited by a continuation prompt both as the module is expanded and when it is visited. The evaluation of a define-syntaxes form is delimited, but unlike define-values, there is no check that the syntax definition completed.
Accessing a module-level variable before it is defined signals a run-time error, just like accessing an undefined global variable. If a module (in its fully expanded form) does not contain a set! for an identifier that defined within the module, then the identifier is a constant after it is defined; its value cannot be changed afterward, not even through reflective mechanisms. The compile-enforce-module-constants parameter, however, can be used to disable enforcement of constants.
When a syntax object representing a module form has a 'module-language syntax property attached, and when the property value is a vector of three elements where the first is a module path (in the sense of module-path?) and the second is a symbol, then the property value is preserved in the corresponding compiled and/or declared module. The third component of the vector should be printable and readable, so that it can be preserved in marshaled bytecode. The racket/base and racket languages attach '#(racket/language-info get-info #f) to a module form. See also module-compiled-language-info, module->language-info, and racket/language-info.
See also Modules and Module-Level Variables, Module Expansion, Phases, and Visits, and Information on Expanded Modules.
> (module duck racket/base (provide num-eggs quack) (define num-eggs 2) (define (quack n) (unless (zero? n) (printf "quack\n") (quack (sub1 n)))))
Changed in version 6.3 of package base: Changed define-syntaxes and define-values to shadow any preceding import, and dropped the use of 'submodule syntax property values on nested module or module* forms.
Submodules in The Racket Guide introduces module*.
Like module, but only for declaring a submodule within a module, and for submodules that may require the enclosing module.
Instead of a module-path after id, #f indicates that all bindings from the enclosing module are visible in the submodule. In that case, begin-for-syntax forms that wrap the module* form shift the phase level of the enclosing module’s bindings relative to the submodule. The macro expander handles such nesting by shifting the phase level of the module* form so that its body starts at phase level 0, expanding, and then reverting the phase level shift; beware that this process can leave syntax objects as 'origin syntax property values out-of-sync with the expanded module.
When a module* form has a module-path, the submodule expansion starts by removing the scopes of the enclosing module, the same as the module form. No shifting compensates for any begin-for-syntax forms that may wrap the submodule.
syntax
(module+ id form ...)
Main and Test Submodules in The Racket Guide introduces module+.
Declares and/or adds to a submodule named id.
Each addition for id is combined in order to form the entire submodule using (module* id #f ....) at the end of the enclosing module. If there is only one module+ for a given id, then (module+ id form ...) is equivalent to (module* id #f form ...), but still moved to the end of the enclosing module.
A syntax property on the module* form with the key 'origin-form-srcloc records the srcloc for every contributing module+ form.
When a module contains multiple submodules declared with module+, then the relative order of the initial module+ declarations for each submodule determines the relative order of the module* declarations at the end of the enclosing module.
A submodule must not be defined using module+ and module or module*. That is, if a submodule is made of module+ pieces, then it must be made only of module+ pieces.
Changed in version 8.9.0.1 of package base: Added 'origin-form-srcloc syntax property.
syntax
(#%module-begin form ...)
The #%module-begin form of racket/base wraps every top-level expression to print non-#<void> results using current-print.
The #%module-begin form of racket/base also declares a configure-runtime submodule (before any other form), unless some form is either an immediate module or module* form with the name configure-runtime. If a configure-runtime submodule is added, the submodule calls the configure function of racket/runtime-config.
syntax
(#%printing-module-begin form ...)
Like #%module-begin, but without adding a configure-runtime submodule.
syntax
(#%plain-module-begin form ...)
syntax
(#%declare declaration-keyword ...)
declaration-keyword = #:cross-phase-persistent | #:empty-namespace | #:require=define | #:unsafe | #:realm identifier
#:cross-phase-persistent —
declares the module as cross-phase persistent, and reports a syntax error if the module does not meet the import or syntactic constraints of a cross-phase persistent module. #:empty-namespace —
declares that module->namespace for this module should produce a namespace with no bindings; limiting namespace support in this way can reduce the lexical information that otherwise must be preserved for the module. #:require=define —
declares that no subsequent definition immediately with the module body is allowed to shadow a #%require (or require) binding. This declaration does not affect shadowing of a module’s initial imports (i.e., the module’s language). #:unsafe —
declares that the module can be compiled without checks that could trigger exn:fail:contract, and the resulting behavior is unspecified for an evaluation where exn:fail:contract should have been raised; see also Unsafe Operations. For example, a use of car can be compiled as a use of unsafe-car, and the behavior is unspecified is unsafe-car is applied to a non-pair. The #:unsafe declaration keyword is allowed only when the current code inspector is the initial one. Macros can generate conditionally unsafe code, depending on the expansion context, by expanding to a use of (variable-reference-from-unsafe? (#%variable-reference)). #:realm identifier —
declares that the module and any procedures within the module are given a realm that is the symbol form of identifier, effectively overriding the value of current-compile-realm.
A #%declare form must appear in a module context or a module-begin context. Each declaration-keyword can be declared at most once within a module body.
Changed in version 6.3 of package base: Added #:empty-namespace.
Changed in version 7.9.0.5: Added #:unsafe.
Changed in version 8.4.0.2: Added #:realm.
Changed in version 8.6.0.9: Added #:require=define.