A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.racket-lang.org/reference/lazy-require.html below:

3.26 Importing Modules Lazily: lazy-require

3.26 Importing Modules Lazily: lazy-require🔗ℹ

(lazy-require [module-path (fun-import ...)] ...)

  fun-import   =   fun-id     |   (orig-fun-id fun-id)

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!

(lazy-require-syntax [module-path (macro-import ...)] ...)

  macro-import   =   macro-id     |   (orig-macro-id macro-id)

Like

lazy-require

but for macros. That is, it defines each

macro-id

as a macro that, when used, dynamically loads the macro’s implementation from the given

module-path

. If

orig-macro-id

is 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-syntax

breaks 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-syntax

requires a particular structure in the macro implementation. (In particular,

lazy-require-syntax

cannot simply be introduced in the client code.) The macro implementation must follow these rules:

  1. the interface module must require the runtime-support module

  2. 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-syntax

to lazily load the implementation of the

ntimes

macro 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