fun-import = fun-id | (orig-fun-id fun-id)(lazy-require [module-path (fun-import ...)] ...)
Defines each fun-id as a function that, when called, dynamically requires the export named orig-fun-id from the module specified by module-path and calls it with the same arguments. If orig-fun-id is not given, it defaults to fun-id.
If the enclosing relative phase level is not 0, then module-path is also placed in a submodule (with a use of define-runtime-module-path-index at phase level 0 within the submodule). Introduced submodules have the names lazy-require-auxn-m, where n is a phase-level number and m is a number.
When the use of a lazily-required function triggers module loading, it also triggers a use of register-external-module to declare an indirect compilation dependency (in case the function is used in the process of compiling a module).
Examples:
> (partition even? '(1 2 3 4 5)) > (greet)starting hello server
hello!
macro-import = macro-id | (orig-macro-id macro-id)(lazy-require-syntax [module-path (macro-import ...)] ...)
Like
lazy-requirebut for macros. That is, it defines each
macro-idas a macro that, when used, dynamically loads the macro’s implementation from the given
module-path. If
orig-macro-idis not given, it defaults to
macro-id.
Use lazy-require-syntax in the implementation of a library with large, complicated macros to avoid a dependence from clients of the library on the macro “compilers.” Note that only macros with exceptionally large compile-time components (such as Typed Racket, which includes a type checker and optimizer) benefit from lazy-require-syntax; typical macros do not.
Warning: lazy-require-syntaxbreaks the invariants that Racket’s module loader and linker rely on; these invariants normally ensure that the references in code produced by a macro are loaded before the code runs. Safe use of
lazy-require-syntaxrequires a particular structure in the macro implementation. (In particular,
lazy-require-syntaxcannot simply be introduced in the client code.) The macro implementation must follow these rules:
the interface module must require the runtime-support module
the compiler module must require the runtime-support module via an absolute module path rather than a relative path
To explain the concepts of “interface, compiler, and runtime-support modules”, here is an example module that exports a macro:
Suppose we want to use
lazy-require-syntaxto lazily load the implementation of the
ntimesmacro transformer. The original module must be split into three parts:
The runtime support module contains the function and value definitions that the macro refers to. The compiler module contains the macro definition(s) themselves—the part of the code that “disappears” after compile time. The interface module lazily loads the macro transformer, but it makes sure the runtime support module is defined at run time by requiring it normally. In a larger example, of course, the runtime support and compiler may both consist of multiple modules.
Here what happens when we don’t separate the runtime support into a separate module:
> (require 'bad-client)require: namespace mismatch;
reference to a module that is not instantiated
module: 'bad-no-runtime
phase: 0
A similar error occurs when the interface module doesn’t introduce a dependency on the runtime support module.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4