- (functor (FUNCTORNAME (ARGUMENTMODULE1 EXPORTS1) ...) FUNCTOREXPORTS BODY)syntax
Defines a "functor", a parameterized module.
This functor definition does not generate any code. This is done by instantiating the functor for specific input modules:
(module MODULENAME = (FUNCTORNAME MODULENAME1 ...))
Inside BODY, references to ARGUMENTMODULE will be replaced by the corresponding MODULENAME argument. The instantiation expands into the complete functor-code BODY and as such can be considered a particular sort of macro-expansion. Note that there is no requirement that a specific export of an argument-module must be syntax or non-syntax - it can be syntax in one instantiation and a procedure definition in another.
ARGUMENTMODULE may also be a list of the form (ALIAS DEFAULT) to allow specifying a default- or optional functor argument in case the instanation doesn't provide one. Optional functor arguments may only be followed by non-optional functor arguments.
The common case of using a functor with a single argument module that is not used elsewhere can be expressed in the following way:
(module NAME = FUNCTORNAME BODY ...)
which is the same as
(begin (module _NAME * BODY ...) (module NAME = (FUNCTORNAME _NAME)))
Since functors exist at compile time, they can be stored in import-libraries via -emit-import-library FUNCTORNAME or -emit-all-import-libraries (see Using the compiler for more information about this). That allows you to import functors for later instantiation. Internally, a functor-definition also defines a module with the same name, but importing this module has no effect. It also has no runtime code, so it is sufficient to merely import it (as opposed to using require-extension or one of its variants, which also loads the run-time part of a module).
Note that functor-instantiation creates a complete copy of the functor body.