4 Module-Processing Helpers

▼ |  | Syntax: Meta-Programming Helpers

1 | Parsing and Specifying Syntax
2 | Syntax Object Helpers
3 | Datum Pattern Matching
4 | Module-Processing Helpers
5 | Macro Transformer Helpers
6 | Reader Helpers
7 | Parsing for Bodies
8 | Unsafe for Clause Transforms
9 | Source Locations
10 | Preserving Source Locations
11 | Non-Module Compilation And Expansion
12 | Trusting Standard Recertifying Transformers
13 | Attaching Documentation to Exports
14 | Contracts for Macro Subexpressions
15 | Macro Testing
16 | Internal-Definition Context Helpers
| Index

► | 4 | Module-Processing Helpers

4.1 | Reading Module Source Code
4.2 | Getting Module Compiled Code
4.3 | Resolving Module Paths to File Paths
4.4 | Simplifying Module Paths
4.5 | Inspecting Modules and Module Dependencies
4.6 | Wrapping Module-Body Expressions

On this page:

4.1`` Reading Module Source Code
with-module-reading-parameterization
check-module-form
4.2`` Getting Module Compiled Code
get-module-code
get-module-path
default-compiled-sub-path
get-metadata-path
moddep-current-open-input-file
exn: get-module-code
4.3`` Resolving Module Paths to File Paths
resolve-module-path
resolve-module-path-index
4.4`` Simplifying Module Paths
collapse-module-path
collapse-module-path-index
4.5`` Inspecting Modules and Module Dependencies
show-import-tree
4.6`` Wrapping Module-Body Expressions
make-wrapping-module-begin

top contents ← prev up next →

### 4`` Module-Processing Helpers🔗ℹ

#### 4.1`` Reading Module Source Code🔗ℹ

(require syntax/modread) | package: base

> procedure (with-module-reading-parameterization thunk) → any
> thunk : (-> any)

Calls thunk with all reader parameters reset to their default values.

> > procedure
> > (check-module-form |  | stx |  |  |  |
> > |  | expected-module-sym |  |  |  |
> > |  | source-v) |  | → |  | (or/c syntax? #f)
> stx : (or/c syntax? eof-object?)
> expected-module-sym : symbol?
> source-v : (or/c string? #f)

Inspects stx to check whether evaluating it will declare a module—at least if module is bound in the top-level to Racket’s module. The syntax object stx can contain a compiled expression. Also, stx can be an end-of-file, on the grounds that read-syntax can produce an end-of-file.

The expected-module-sym argument is currently ignored. In previous versions, the module form stx was obliged to declare a module who name matched expected-module-sym.

If stx can declare a module in an appropriate top-level, then the check-module-form procedure returns a syntax object that certainly will declare a module (adding explicit context to the leading module if necessary) in any top-level. Otherwise, if source-v is not #f, a suitable exception is raised using the write form of the source in the message; if source-v is #f, #f is returned.

If stx is eof or eof wrapped as a syntax object, then an error is raised or #f is returned.

#### 4.2`` Getting Module Compiled Code🔗ℹ

(require syntax/modcode) | package: base

> > procedure
> > (get-module-code |  | path |  |  |  |
> > | [ | #:submodule-path submodule-path |  |  |  |
> > |  | #:sub-path compiled-subdir0 |  |  |  |
> > |  | compiled-subdir |  |  |  |
> > |  | #:roots roots |  |  |  |
> > |  | #:compile compile-proc0 |  |  |  |
> > |  | compile-proc |  |  |  |
> > |  | #:extension-handler ext-proc0 |  |  |  |
> > |  | ext-proc |  |  |  |
> > |  | #:notify notify-proc |  |  |  |
> > |  | #:source-reader read-syntax-proc |  |  |  |
> > |  | #:rkt-try-ss? rkt-try-ss? |  |  |  |
> > |  | #:choose choose-proc]) |  | → |  | any
> path : path-string?
> submodule-path : (listof symbol?) = '()
> | compiled-subdir0 |  | : |  |
> (or/c (and/c path-string? relative-path?)
> (listof (and/c path-string? relative-path?)))
> |  |  | = |  | (use-compiled-file-paths)
> | compiled-subdir |  | : |  |
> (or/c (and/c path-string? relative-path?)
> (listof (and/c path-string? relative-path?)))
> |  |  | = |  | compiled-subdir0
> | roots |  | : |  | (listof (or/c path-string? 'same))
> |  |  | = |  | (current-compiled-file-roots)
> compile-proc0 : (any/c . -> . any) = compile
> compile-proc : (any/c . -> . any) = compile-proc0
> ext-proc0 : (or/c #f (path? boolean? . -> . any)) = #f
> ext-proc : (or/c #f (path? boolean? . -> . any)) = ext-proc0
> notify-proc : (any/c . -> . any) = void
> | read-syntax-proc |  | : |  | (any/c input-port? . -> . (or/c syntax? eof-object?))
> |  |  | = |  | read-syntax
> rkt-try-ss? : boolean? = #t
> | choose-proc |  | : |  |
> (or/c (-> path? path? path?
> (or/c 'src 'zo 'so #f))
> #f)
> |  | = |  | #f

Returns a compiled expression for the declaration of the module specified by path and submodule-path, where submodule-path is empty for a root module or a list for a submodule.

The roots, compiled-subdir, choose-proc, and rkt-try-ss? and submodule-path arguments determine which file is consulted to find the compiled code. If the default values are provided, then this function uses the same logic as the default value of current-load/use-compiled. In more detail:

- If submodule-path is not the empty list, then the compiled code will never be located in a dynamic extension; instead the original source or a "zo" file will be used.

- The rkt-try-ss? argument defaults to #t. If it is not #f, then if path ends in ".rkt", then the corresponding file ending in ".ss" will be tried as well.

- The choose-proc argument is called with the original source file (which might have had its ending changed, c.f. the rkt-try-ss? argument) and two other paths that end with "zo" and "so" (but they are not necessarily the paths that get-module-code uses). If the choose-proc returns 'src, then compiled files are not used. If it returns any other result, the result is ignored. In previous versions of this function, the choose-proc offered more control over which file was used but it no longer does; the current interface is kept for backwards compatibility.

- The compiled-subdir argument defaults to (use-compiled-file-paths); it specifies the sub-directories to search for a compiled version of the module. If compiled-subdir is a list, then the first directory that contains a file with an appropriate name is used as the compiled file.

- The roots list specifies a compiled-file search path in the same way as the current-compiled-file-roots parameter; it defaults to the current value of current-compiled-file-roots.

The compile-proc argument defaults to compile. This procedure is used to compile module source if an already-compiled version is not available. If submodule-path is not '(), then compile-proc must return a compiled module form.

The ext-proc argument defaults to #f. If it is not #f, it must be a procedure of two arguments that is called when a native-code version of path should be used. In that case, the arguments to ext-proc are the path for the dynamic extension, and a boolean indicating whether the extension is a _loader file (#t) or not (#f).

If a dynamic extension is preferred or is the only file that exists, it is supplied to ext-proc when ext-proc is #f, or an exception is raised (to report that an extension file cannot be used) when ext-proc is #f.

If notify-proc is supplied, it is called for the file (source, ".zo" or dynamic extension) that is chosen.

If read-syntax-proc is provided, it is used to read the module from a source file (but not from a bytecode file).

Changed in version 6.90.0.7 of package base: Use (default-compiled-sub-path) for the default value of compiled-subdir.
Changed in version 8.6.0.12: Generalize the #:sub-path argument, change #:sub-path’s default to (use-compiled-file-paths), and pay less attention to the #:choose argument.

> > procedure
> > (get-module-path |  | path |
> > |  | #:submodule? submodule? |
> > | [ | #:sub-path compiled-subdir0 |
> > |  | compiled-subdir |
> > |  | #:roots roots |
> > |  | #:rkt-try-ss? rkt-try-ss? |
> > |  | #:choose choose-proc]) |
> | → |  |
> path? |  | (or/c 'src 'zo 'so)
> path : path-string?
> submodule? : boolean?
> | compiled-subdir0 |  | : |  |
> (or/c (and/c path-string? relative-path?)
> (listof (and/c path-string? relative-path?)))
> |  |  | = |  | (use-compiled-file-paths)
> | compiled-subdir |  | : |  |
> (or/c (and/c path-string? relative-path?)
> (listof (and/c path-string? relative-path?)))
> |  |  | = |  | compiled-subdir0
> | roots |  | : |  | (listof (or/c path-string? 'same))
> |  |  | = |  | (current-compiled-file-roots)
> rkt-try-ss? : boolean? = #t
> choose-proc : any/c = #f

Produces two values. The first is the path of the latest source or compiled file for the module specified by path; this result is the path of the file that get-module-code would read to produce a compiled module expression. The second value is 'src, 'zo, or 'so, depending on whether the first value represents a Racket source file, a compiled bytecode file, or a native library file.

The compiled-subdir, roots, choose-proc, and rkt-try-ss? arguments are interpreted the same as by get-module-code.

The submodule? argument represents whether the desired module is a submodule of the one specified by path. When submodule? is true, the result path never refers to a dynamic extension and the result symbol is never 'so, as native libraries cannot provide submodules.

Changed in version 6.90.0.7 of package base: Use (default-compiled-sub-path) for the default value of compiled-subdir.
Changed in version 8.6.0.12: Generalize the #:sub-path argument, change #:sub-path’s default to (use-compiled-file-paths), and pay less attention to the #:choose argument.

> procedure (default-compiled-sub-path) → path-string?

If (use-compiled-file-paths) is not '(), returns the first element of the list. Otherwise, returns "compiled".

This function used to provide the default for the #:sub-path argument to get-module-code and get-module-path, but it is no longer used by this library.

Added in version 6.90.0.7 of package base.

> > procedure
> > (get-metadata-path |  | path |  |  |  |
> > | [ | #:roots roots] |  |  |  |
> > |  | sub-path ...+) |  | → |  | path?
> path : path-string?
> | roots |  | : |  | (listof (or/c path-string? 'same))
> |  |  | = |  | (current-compiled-file-roots)
> sub-path : (or/c path-string? 'same)

Constructs the path used to store compilation metadata for a source file stored in the directory path. The argument roots specifies the possible root directories to consider and to search for an existing file. The sub-path arguments specify the subdirectories and filename of the result relative to the chosen root. For example, the compiled ".zo" file for "/path/to/source.rkt" might be stored in (get-metadata-path (build-path "/path/to") "compiled" "source_rkt.zo").

> parameter (moddep-current-open-input-file)
> → (path-string? . -> . input-port?)
> (moddep-current-open-input-file proc) → void?
> proc : (path-string? . -> . input-port?)

A parameter whose value is used like open-input-file to read a module source or ".zo" file.

> > struct
> > (struct |  | exn:get-module-code exn:fail (path)
> #:extra-constructor-name make-exn:get-module-code)
> path : path?

An exception structure type for exceptions raised by get-module-code.

#### 4.3`` Resolving Module Paths to File Paths🔗ℹ

(require syntax/modresolve) | package: base

> > procedure
> > (resolve-module-path |  | module-path-v |
> > | [ | rel-to-path-v]) |
> | → |  |
> (or/c path? symbol?
> (cons/c 'submod (cons/c (or/c path? symbol?) (listof symbol?))))
> module-path-v : module-path?
> rel-to-path-v : (or/c #f path-string? (-> any)) = #f

Resolves a module path to filename path. The module path is resolved relative to rel-to-path-v if it is a path string (assumed to be for a file), to the directory result of calling the thunk if it is a thunk, or to the current directory otherwise.

When module-path-v refers to a module using a collection-based path, resolution invokes the current module name resolver, but without loading the module even if it is not declared. Beware that concurrent resolution in namespaces that share a module registry can create race conditions when loading modules; see also namespace-call-with-registry-lock.

> > procedure
> > (resolve-module-path-index |  | module-path-index |
> > | [ | rel-to-path-v]) |
> | → |  |
> (or/c path? symbol?
> (cons/c 'submod (cons/c (or/c path? symbol?) (listof symbol?))))
> module-path-index : module-path-index?
> rel-to-path-v : (or/c #f path-string? (-> any)) = #f

Like resolve-module-path but the input is a module path index; in this case, the rel-to-path-v base is used where the module path index contains the “self” index. If module-path-index depends on the “self” module path index, then an exception is raised unless rel-to-path-v is a path string.

See module-path-index-resolve.

Examples:

> > (resolve-module-path-index
> (module-path-index-join 'racket #f))
> #<path:/pbulk/work/lang/racket/work/racket-8.15/collects/racket/main.rkt>
> > (resolve-module-path-index
> (module-path-index-join "apple.rkt" #f))
> #<path:/pbulk/work/lang/racket/work/racket-8.15/share/pkgs/racket-doc/syntax/apple.rkt>
> > (resolve-module-path-index
> (module-path-index-join '(submod "." test) #f)
> (string->path "banana.rkt"))
> '(submod #<path:banana.rkt> test)

#### 4.4`` Simplifying Module Paths🔗ℹ

(require syntax/modcollapse) | package: base

> > procedure
> > (collapse-module-path |  | module-path-v |  |  |  |
> > |  | rel-to-module-path-v) |  | → |  | module-path?
> module-path-v : module-path?
> | rel-to-module-path-v |  | : |  |
> (or/c module-path?
> (-> module-path?))

Returns a “simplified” module path by combining module-path-v with rel-to-module-path-v, where the latter must have one of the following forms: a '(lib ....) or symbol module path; a '(file ....) module path; a '(planet ....) module path; a path; '(quote symbol); a '(submod base symbol ...) module path where base would be allowed; or a thunk to generate one of those.

The result can be a path if module-path-v contains a path element that is needed for the result, or if rel-to-module-path-v is a non-string path that is needed for the result. Similarly, the result can be 'submod wrapping a path. Otherwise, the result is a module path (in the sense of module-path?) that is not a plain filesystem path.

When the result is a 'lib or 'planet module path, it is normalized so that equivalent module paths are represented by equal? results. When the result is a 'submod module path, it contains only symbols after the base module path, and the base is normalized in the case of a 'lib or 'planet base.

Examples:

> > (collapse-module-path "m.rkt" '(lib "n/main.rkt"))
> '(lib "n/m.rkt")
> > (collapse-module-path '(submod "." x) '(lib "n/main.rkt"))
> '(submod (lib "n/main.rkt") x)
> > (collapse-module-path '(submod "." x) '(submod (lib "n/main.rkt") y))
> '(submod (lib "n/main.rkt") y x)

> > procedure
> > (collapse-module-path-index |  | module-path-index |
> > |  | rel-to-module-path-v) |
> → module-path?
> module-path-index : module-path-index?
> | rel-to-module-path-v |  | : |  |
> (or/c module-path?
> (-> module-path?))
> (collapse-module-path-index module-path-index)
> → (or/c module-path? #f)
> module-path-index : module-path-index?

Like collapse-module-path when given two arguments, but the input is a module path index; in this case, the rel-to-module-path-v base is used where the module path index contains the “self” index (see module-path-index-split).

When given a single argument, collapse-module-path-index returns a module path that is relative if the given module path index is relative, except that it returns #f if its argument is the “self” module path index. A resulting module path is not necessarily normalized.

Changed in version 6.1.1.8 of package base: Added the one-argument variant for collapsing a relative module path index.
Changed in version 6.9.0.5: Added support for the “self” module path index as the only argument, which meant extending the result contract to include #f

#### 4.5`` Inspecting Modules and Module Dependencies🔗ℹ

(require syntax/moddep) | package: base

Re-exports syntax/modread, syntax/modcode, syntax/modcollapse, and syntax/modresolve, in addition to the following:

> > procedure
> > (show-import-tree |  | module-path-v |  |  |  |
> > | [ | #:dag? dag? |  |  |  |
> > |  | #:path-to path-to-module-path-v |  |  |  |
> > |  | #:show show]) |  | → |  | void?
> module-path-v : module-path?
> dag? : any/c = #f
> path-to-module-path-v : (or/c #f module-path?) = #f
> | show |  | : |  | (string? any/c string? (or/c #f exact-integer?) . -> . any)
> |  |  | = |  |
> (lambda (indent path require-mode phase)
> (printf "~a~a~a ~a\n" indent path require-mode phase))

A debugging aid that prints (by default) the import hierarchy starting from a given module path. Supply an alternate show function to handle each path instead of having it printed; the second argument is a result of resolved-module-path-name.

If dag? is true, then a module is passed to show only the first time is encountered in the hierarchy at a given phase.

If path-to-module-path-v is a module path, then only the spines of the tree that reach path-to-module-path-v are shown.

Changed in version 6.12.0.4 of package base: Added the #:dag? and #:path-to arguments.
Changed in version 7.0.0.10: Added the #:show argument.

#### 4.6`` Wrapping Module-Body Expressions🔗ℹ

(require syntax/wrap-modbeg) | package: base

Added in version 6.0.0.1 of package base.

> > procedure
> > (make-wrapping-module-begin |  | wrap-form |
> > | [ | module-begin-form]) |
> → (syntax? . -> . syntax?)
> wrap-form : syntax?
> module-begin-form : syntax? = #'#%plain-module-begin

Provided for-syntax.

Constructs a function that is suitable for use as a #%module-begin replacement, particularly to replace the facet of #%module-begin that wraps each top-level expression to print the expression’s result(s).

The function takes a syntax object and returns a syntax object using module-begin-form. Assuming that module-begin-form resembles #%plain-module-begin, each top-level expression expr will be wrapped as (wrap-form expr), while top-level declarations (such as define-values and require forms) are left as-is. Expressions are detected after macro expansion and begin splicing, and expansion is interleaved with declaration processing as usual.

top contents ← prev up next →