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
get-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 ← 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? false/c)
> stx : (or/c syntax? eof-object?)
> expected-module-sym : symbol?
> source-v : (or/c string? false/c)

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 |  |  |  |
> > |  | #:choose choose-proc |  |  |  |
> > |  | #:notify notify-proc |  |  |  |
> > |  | #:source-reader read-syntax-proc |  |  |  |
> > |  | #:rkt-try-ss? rkt-try-ss?]) |  | → |  | any
> path : path-string?
> submodule-path : (listof symbol?) = '()
> | compiled-subdir0 |  | : |  | (and/c path-string? relative-path?)
> |  |  | = |  | (get-default-compiled-sub-path)
> | compiled-subdir |  | : |  | (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 false/c (path? boolean? . -> . any)) = #f
> | ext-proc |  | : |  | (or/c false/c (path? boolean? . -> . any))
> |  |  | = |  | ext-proc0
> | choose-proc |  | : |  |
> (path? path? path?
> . -> .
> (or/c (symbols 'src 'zo 'so) false/c))
> |  |  | = |  | (lambda (src zo so) #f)
> 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

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 compiled-subdir argument defaults to (get-default-compiled-sub-path); it specifies the sub-directory to search for a compiled version of the module. The roots list specifies a compiled-file search path in the same way as the current-compiled-file-roots parameter.

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 extension, and a boolean indicating whether the extension is a _loader file (#t) or not (#f).

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 a procedure that takes three paths: a source path, a ".zo" file path, and an extension path (for a non-_loader extension). Some of the paths may not exist. The result should be either 'src, 'zo, 'so, or #f, indicating which variant should be used or (in the case of #f) that the default choice should be used.

The default choice is computed as follows: if a ".zo" version of path is available and newer than path itself (in one of the directories specified by compiled-subdir), then it is used instead of the source. Native-code versions of path are ignored, unless only a native-code non-_loader version exists (i.e., path itself does not exist). A _loader extension is selected a last resort.

If an 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 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 (get-default-compiled-sub-path) for the default value of compiled-subdir.

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

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 is never a 'so path, as native libraries cannot provide submodules.

Changed in version 6.90.0.7 of package base: Use (get-default-compiled-sub-path) for the default value of compiled-subdir.

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

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

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.

> > 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:/home/scheme/pltbuild/racket/racket/collects/racket/main.rkt>
> > (resolve-module-path-index
> (module-path-index-join "apple.rkt" #f))
> #<path:/home/scheme/pltbuild/racket/build/user/7.2/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 ← prev up next →