can be defined in one and shared with another. The defining module is exporting bindings; the other module is importing them. In practice, an importing or exporting module is usually a self-contained source file. But everything here applies equally to , which can share bindings the same way.
It’s conventional to think about importing & exporting in terms of bindings rather than . Why? Because a variable = an identifier + a binding. While it’s often true that a binding travels with its original identifier, it’s not mandatory—as we will see below, the identifier can be altered along the way (though the binding will not be).
By default, all bindings defined in a module are private to that module. To make a binding available to other modules, use provide:
Though provide can be used anywhere within a module, Racketeers often consolidate them at the top, to summarize the public interface of the module:
To export every binding newly defined within a module, use the shorthand all-defined-out:
1 2 3 4 5 6
Any bindings available in the module can be exported, not just those that are defined there. For instance, bindings that are already available through the current #lang can also be exported:
These bindings, however, are not included in all-defined-out. To export bindings that have been imported from a certain module, list them individually, or use all-from-out to export all of them:
To make the external name of a binding different from its internal name, use provide with rename-out:
A practical use of rename-out is to chain together #%module-begin macros in a language. In this example from bf, the identifier #%module-begin is used twice: within the module it refers to the #%module-begin macro from br/quicklang; outside the module, it will refer to bf-module-begin:
1 2 3 4 5 6
Every module gets its initial set of bindings from its expander. In a module expression, the expander is designated explicitly. In a source file, the #lang line specifies a reader, which converts the source file into a module expression with an expander designation (see the #lang line for more about this conversion):
1 2 3 4 5 6
#lang br ;; all bindings exported by the `br` expander are available here (module sub pollen ;; all bindings exported by `pollen` are available here )
Beyond that, bindings can be imported from other modules with require:
#lang br (token 'FOO "bar") ; no binding for `token` yet
token: unbound identifier in module in: token
1 2 3
#lang br (require brag/support) ; provides `token` (token 'FOO "bar")
(token-struct 'FOO "bar" #f #f #f #f #f)
Bindings can be imported from submodules by using submod, which uses a path-like specification:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
The evaluation of a module occurs in a series of separate . Consequently, each phase gets its own separate round of importing & exporting. Bindings that are imported during a certain phase are not automatically visible in other phases.
For instance, this macro returns code that relies on nand, a function imported from racket/bool:
This works because an ordinary require, as seen here, imports bindings at phase 0. The macro refers to nand within the it returns. Though the macro is compiled during phase 1, its syntax object isn’t evaluated until phase 0. So this reference to nand works.
This macro, however, fails with a nand: undefined error:
This time, the macro also tries to use nand outside the syntax object. This reference to nand will be evaluated during phase 1, when the macro is compiled. But racket/bool isn’t available in phase 1—only phase 0. Hence the error.
This problem can be cured with for-syntax, which explicitly imports a module at phase 1, where it can be visible to macros:
1 2 3 4 5 6 7
And just to come full circle: if the phase-0 require for racket/bool is removed, the nand inside the macro (at phase 1) will still print, but back in phase 0, an unbound-identifier error will arise:
1 2 3 4 5 6
'phase-1 nand: unbound identifier in module in: nand