6.2 Module Syntax

► |  | The Racket Guide

1 | Welcome to Racket
2 | Racket Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Creating Languages
18 | Concurrency and Synchronization
19 | Performance
20 | Parallelism
21 | Running and Creating Executables
22 | More Libraries
23 | Dialects of Racket and Scheme
24 | Command-Line Tools and Your Editor of Choice
| Bibliography
| Index

▼ | 6 | Modules

6.1 | Module Basics
6.2 | Module Syntax
6.3 | Module Paths
6.4 | Imports: require
6.5 | Exports: provide
6.6 | Assignment and Redefinition
6.7 | Modules and Macros
6.8 | Protected Exports

► | 6.2 | Module Syntax

6.2.1 | The module Form
6.2.2 | The #lang Shorthand
6.2.3 | Submodules
6.2.4 | Main and Test Submodules

On this page:

6.2.1`` The module Form
6.2.2`` The #lang Shorthand
6.2.3`` Submodules
6.2.4`` Main and Test Submodules

top contents ← prev up next →

#### 6.2`` Module Syntax🔗ℹ

The #lang at the start of a module file begins a shorthand for a module form, much like ' is a shorthand for a quote form. Unlike ', the #lang shorthand does not work well in a REPL, in part because it must be terminated by an end-of-file, but also because the longhand expansion of #lang depends on the name of the enclosing file.

##### 6.2.1`` The module Form🔗ℹ

The longhand form of a module declaration, which works in a REPL as well as a file, is

> > (module name-id initial-module-path
> > decl ...)

where the name-id is a name for the module, initial-module-path is an initial import, and each decl is an import, export, definition, or expression. In the case of a file, name-id normally matches the name of the containing file, minus its directory path or file extension, but name-id is ignored when the module is required through its file’s path.

The initial-module-path is needed because even the require form must be imported for further use in the module body. In other words, the initial-module-path import bootstraps the syntax that is available in the body. The most commonly used initial-module-path is racket, which supplies most of the bindings described in this guide, including require, define, and provide. Another commonly used initial-module-path is racket/base, which provides less functionality, but still much of the most commonly needed functions and syntax.

For example, the "cake.rkt" example of the previous section could be written as

> (module cake racket
> (provide print-cake)
> (define (print-cake n)
> (show " ~a " n #\.)
> (show " .-~a-. " n #\|)
> (show " | ~a | " n #\space)
> (show "---~a---" n #\-))
> (define (show fmt n ch)
> (printf fmt (make-string n ch))
> (newline)))

Furthermore, this module form can be evaluated in a REPL to declare a cake module that is not associated with any file. To refer to such an unassociated module, quote the module name:

Examples:

> > (require 'cake)
> > (print-cake 3)
> ...
> .-|||-.
> ---------

Declaring a module does not immediately evaluate the body definitions and expressions of the module. The module must be explicitly required at the top level to trigger evaluation. After evaluation is triggered once, later requires do not re-evaluate the module body.

Examples:

> > (module hi racket
> (printf "Hello\n"))
> > (require 'hi)
> Hello
> > (require 'hi)

##### 6.2.2`` The #lang Shorthand🔗ℹ

The body of a #lang shorthand has no specific syntax, because the syntax is determined by the language name that follows #lang.

In the case of #lang racket, the syntax is

> #lang racket
> decl ...

which reads the same as

> (module name racket
> decl ...)

where name is derived from the name of the file that contains the #lang form.

The #lang racket/base form has the same syntax as #lang racket, except that the longhand expansion uses racket/base instead of racket. The #lang scribble/manual form, in contrast, has a completely different syntax that doesn’t even look like Racket, and which we do not attempt to describe in this guide.

Unless otherwise specified, a module that is documented as a “language” using the #lang notation will expand to module in the same way as #lang racket. The documented language name can be used directly with module or require, too.

##### 6.2.3`` Submodules🔗ℹ

A module form can be nested within a module, in which case the nested module form declares a submodule. Submodules can be referenced directly by the enclosing module using a quoted name. The following example prints "Tony" by importing tiger from the zoo submodule:

> > "park.rkt"

> > > #lang racket
> > > (module zoo racket
> > > (provide tiger)
> > > (define tiger "Tony"))
> > > (require 'zoo)
> > > tiger

Running a module does not necessarily run its submodules. In the above example, running "park.rkt" runs its submodule zoo only because the "park.rkt" module requires the zoo submodule. Otherwise, a module and each of its submodules can be run independently. Furthermore, if "park.rkt" is compiled to a bytecode file (via raco make), then the code for "park.rkt" or the code for zoo can be loaded independently.

Submodules can be nested within submodules, and a submodule can be referenced directly by a module other than its enclosing module by using a submodule path.

A module* form is similar to a nested module form:

> > (module* name-id initial-module-path-or-#f
> > decl ...)

The module* form differs from module in that it inverts the possibilities for reference between the submodule and enclosing module:

- A submodule declared with module can be required by its enclosing module, but the submodule cannot require the enclosing module or lexically reference the enclosing module’s bindings.

- A submodule declared with module* can require its enclosing module, but the enclosing module cannot require the submodule.

In addition, a module* form can specify #f in place of an initial-module-path, in which case the submodule sees all of the enclosing module’s bindings—including bindings that are not exported via provide.

One use of submodules declared with module* and #f is to export additional bindings through a submodule that are not normally exported from the module:

> > "cake.rkt"

> > > #lang racket
> > > (provide print-cake)
> > > (define (print-cake n)
> > > (show " ~a " n #\.)
> > > (show " .-~a-. " n #\|)
> > > (show " | ~a | " n #\space)
> > > (show "---~a---" n #\-))
> > > (define (show fmt n ch)
> > > (printf fmt (make-string n ch))
> > > (newline))
> > > (module* extras #f
> > > (provide show))

In this revised "cake.rkt" module, show is not imported by a module that uses (require "cake.rkt"), since most clients of "cake.rkt" will not want the extra function. A module can require the extra submodule using (require (submod "cake.rkt" extras)) to access the otherwise hidden show function.See submodule paths for more information on submod.

##### 6.2.4`` Main and Test Submodules🔗ℹ

The following variant of "cake.rkt" includes a main submodule that calls print-cake:

> > "cake.rkt"

> > > #lang racket
> > > (define (print-cake n)
> > > (show " ~a " n #\.)
> > > (show " .-~a-. " n #\|)
> > > (show " | ~a | " n #\space)
> > > (show "---~a---" n #\-))
> > > (define (show fmt n ch)
> > > (printf fmt (make-string n ch))
> > > (newline))
> > > (module* main #f
> > > (print-cake 10))

Running a module does not run its module*-defined submodules. Nevertheless, running the above module via racket or DrRacket prints a cake with 10 candles, because the main submodule is a special case.

When a module is provided as a program name to the racket executable or run directly within DrRacket, if the module has a main submodule, the main submodule is run after its enclosing module. Declaring a main submodule thus specifies extra actions to be performed when a module is run directly, instead of required as a library within a larger program.

A main submodule does not have to be declared with module*. If the main module does not need to use bindings from its enclosing module, it can be declared with module. More commonly, main is declared using module+:

> > (module+ name-id
> > decl ...)

A submodule declared with module+ is like one declared with module* using #f as its initial-module-path. In addition, multiple module+ forms can specify the same submodule name, in which case the bodies of the module+ forms are combined to create a single submodule.

The combining behavior of module+ is particularly useful for defining a test submodule, which can be conveniently run using raco test in much the same way that main is conveniently run with racket. For example, the following "physics.rkt" module exports drop and to-energy functions, and it defines a test module to hold unit tests:

> > "physics.rkt"

> > > #lang racket
> > > (module+ test
> > > (require rackunit)
> > > (define ε 1e-10))
> > > (provide drop
> > > to-energy)
> > > (define (drop t)
> > > (* 1/2 9.8 t t))
> > > (module+ test
> > > (check-= (drop 0) 0 ε)
> > > (check-= (drop 10) 490 ε))
> > > (define (to-energy m)
> > > (* m (expt 299792458.0 2)))
> > > (module+ test
> > > (check-= (to-energy 0) 0 ε)
> > > (check-= (to-energy 1) 9e+16 1e+15))

Importing "physics.rkt" into a larger program does not run the drop and to-energy tests—or even trigger the loading of the test code, if the module is compiled—but running raco test physics.rkt at a command line runs the tests.

The above "physics.rkt" module is equivalent to using module*:

> > "physics.rkt"

> > > #lang racket
> > > (provide drop
> > > to-energy)
> > > (define (drop t)
> > > (* 1/2 49/5 t t))
> > > (define (to-energy m)
> > > (* m (expt 299792458 2)))
> > > (module* test #f
> > > (require rackunit)
> > > (define ε 1e-10)
> > > (check-= (drop 0) 0 ε)
> > > (check-= (drop 10) 490 ε)
> > > (check-= (to-energy 0) 0 ε)
> > > (check-= (to-energy 1) 9e+16 1e+15))

Using module+ instead of module* allows tests to be interleaved with function definitions.

The combining behavior of module+ is also sometimes helpful for a main module. Even when combining is not needed, (module+ main ....) is preferred as it is more readable than (module* main #f ....).

top contents ← prev up next →