~ chicken-core (master) /manual/Modules
Trap1[[tags: manual]]2[[toc:]]345=== Modules67To allow control over visible bindings and to organize code in namespaces,8a module system is available. A ''module''9defines a set of toplevel expressions that are initially evaluated in10an empty syntactical environment. By ''importing'' other modules,11exported value- and syntax-bindings are made visible inside the12environment of the module that imports them.1314Note that modules are purely syntactical - they do not change the15control flow or delay the execution of the contained toplevel16forms. The body of a module is executed at load-time, when code is17loaded or imported, just like normal18toplevel expressions. Exported syntax-definitions are compiled as19well, and can be accessed in interpreted or compiled code by loading20and importing the compiled file that contains the module.2122Imported toplevel bindings are mutable and can be assigned23(with {{set!}}), any modifications24to these will change the global value and will be visible to other25modules that export or import the same toplevel binding.2627A module is initially empty (has no visible bindings with the exception28of {{import}} and {{cond-expand}}). You must at least29import the {{scheme}} or {{(scheme base)}} modules to do anything useful.3031CHICKEN's module system has the following features:3233* Separation of compile/expansion-time and run-time code is provided, which allows cross compilation34* Supports batch-compilation of separate compilation units35* Imports can be lexically scoped36* Parameterized modules are supported3738At toplevel and outside of a module, the initially available bindings39are everything that is exported from the [[Module scheme|scheme]],40[[Module (chicken base)|(chicken base)]] and41[[Module (chicken syntax)|(chicken syntax)]] modules.424344==== module4546<macro>(module NAME (EXPORT ...) BODY ...)</macro>47<macro>(module NAME (EXPORT ...) FILENAME)</macro>48<macro>(module NAME * BODY ...)</macro>49<macro>(module NAME = (FUNCTORNAME MODULENAME1 ...))</macro>50<macro>(module NAME = FUNCTORNAME BODY ...)</macro>5152Defines a module with the name {{NAME}}, a set of exported bindings and53a contained sequence of toplevel expressions that are evaluated in an54empty syntactical environment.5556{{NAME}} and {{FUNCTORNAME}} should be symbols or lists of symbols and57integers, where {{(foo bar baz)}} is equivalent to {{foo.bar.baz}}.5859{{(EXPORT ...)}} should be an export-specification which holds a list60of identifiers to be exported from the module and which should be61visible when imported into another module or the toplevel62environment. {{EXPORT}} may have any of the following forms:6364{{IDENTIFIER}} names a value- or syntax binding to be exported.6566{{(IDENTIFIER1 ...)}} or {{(syntax: IDENTIFIER1 ...)}} exports67{{IDENTIFIER1}} (which should name a macro) and also arranges for the68remaining identifiers in the list to be visible as value bindings in the expansion of69the macro (this is a hint to the module expander to export bindings70referenced by syntax-definitions which make use of them, but which71would normally be internal to the module - which gives more72opportunities for optimization).7374{{(interface: INTERFACENAME)}} adds all exports defined for the given75interface to be added to the list of exported identifiers of this76module.7778As a special case, specifying {{*}} instead of an export-list will79export all definitions. As another special case, the export-list may80be a symbol naming an interface.8182When the {{BODY}} consists of a single string, it is treated83like {{(include FILENAME)}}.8485{{(module NAME = (FUNCTORNAME MODULENAME1 ...))}} instantiates86a ''functor'' (see below for information about functors).8788{{(module NAME = FUNCTORNAME BODY ...)}} is a special form of89''functor instantiation'' where the {{BODY}} implements a module90satisfying a single functor argument to {{FUNCTORNAME}}.9192Nested modules, modules not at toplevel (i.e. local modules) or93mutually recursive modules are not supported.9495When compiled, the module information, including exported syntax96is stored in the generated binary and available when loading97it into interpreted or compiled code. Note that this is different98to normal syntax (outside of module declarations), which are normally99not exported from compiled code.100101Note that the module system is only a device for controlling the102mapping of identifiers to value or syntax bindings. Modules do not103instantiate separate environments that contain their own bindings, as104do many other module systems. Redefinition or assignment of value or105syntax bindings will modify the original, imported definition.106107Syntax expansions may result in module-definitions, but must be108at toplevel.109110111==== export112113<macro>(export EXPORT ...)</macro>114115Allows augmenting module-exports from inside the module-body.116{{EXPORT}} is if the same form as an export-specifier in a117{{module}} export list. An export must precede its first occurrence118(either use or definition).119120If used outside of a module, then this form does nothing.121122==== export/rename123124<macro>(export/rename (NAME EXPORT) ...)</macro>125126Allows augmenting module-exports from inside the module-body.127Each argument should be a two-element list containing the name128of the local value- or syntax-definition (NAME) and the name under which the129definition should be exported (EXPORT).130131If used outside of a module, then this form does nothing.132133==== import134135<macro>(import IMPORT ...)</macro>136137Imports module bindings into the current syntactical environment.138The visibility of any imported bindings is limited to the current139module, if used inside a module-definition, or to the current140compilation unit, if compiled and used outside of a module.141142Importing a module will also load or link its associated library when143needed.144145{{IMPORT}} may be a module name or an ''import specifier'', where a146module name is either a symbol or a list of symbols and integers.147An {{IMPORT}} defines a set of bindings that are to be made visible148in the current scope.149150===== only151152 [import specifier] (only IMPORT IDENTIFIER ...)153154Only import the listed value- or syntax bindings from the set given155by {{IMPORT}}.156157===== except158159 [import specifier] (except IMPORT IDENTIFIER ...)160161Remove the listed identifiers from the import-set defined by {{IMPORT}}.162163===== rename164165 [import specifier] (rename IMPORT (OLD1 NEW1) ...)166167Renames identifiers imported from {{IMPORT}}.168169===== prefix170171 [import specifier] (prefix IMPORT SYMBOL)172173Prefixes all imported identifiers with {{SYMBOL}}.174175==== import-syntax176177<macro>(import-syntax IMPORT ...)</macro>178179Similar to {{import}} but only import syntactic definitions such as180macros, as well as identifiers, but does not load or link the library181containing the module.182183==== import-for-syntax184185<macro>(import-for-syntax IMPORT ...)</macro>186187Similar to {{import}}, but imports exported bindings of a module into188the environment in which macro transformers are evaluated.189190Note: currently this isn't fully correct - value bindings are still191imported into the normal environment because a separate import192environment for syntax has not been implemented (syntactic bindings193are kept separate correctly).194195==== import-syntax-for-syntax196197<macro>(import-syntax-for-syntax IMPORT ...)</macro>198199Combination of {{import-syntax}} and {{import-for-syntax}}. Loads200syntactic definitions and valinside the environment in which macro201transformers are evaluated but do not load the associated library.202203==== reexport204205<macro>(reexport IMPORT ...)</macro>206207Imports {{IMPORT ...}} and automatically exports all imported identifiers.208This can be used to build ''compound modules'': modules that just extend209other modules:210211<enscript hightlight=scheme>212(module r4rs ()213 (import scheme (chicken module))214 (reexport215 (except scheme216 dynamic-wind values call-with-values eval scheme-report-environment217 null-environment interaction-environment)))218</enscript>219220221=== define-interface222223<macro>(define-interface INTERFACENAME (EXPORT ...))</macro>224225Defines an ''interface'', a group of exports that can be used in226module-definitions using the {{(interface: INTERFACE)}} syntax.227See the definition of {{module}} above for an explanation of228{{EXPORT}} specifications.229230Interface names use a distinct global namespace. Interfaces defined231inside modules are not visible outside of the module body.232233234=== import libraries235236''import libraries'' allow the syntactical (compile-time)237and run-time parts of a compiled module to be separated into a normal238compiled file and a shared library that only contains macro definitions239and module information. This reduces the size of executables and240simplifies compiling code that uses modules for a different architecture241than the machine the compiler is executing on (i.e. "cross" compilation).242243By using the {{emit-import-library}} compiler-option or declaration,244a separate file is generated that only contains syntactical information245(including macros) for a module. {{import}} will automatically find and246load an import library for a currently unknown module, if the import-247library is either in the extension repository or the current include248path. Interpreted code249can simply load the import library to make the module-definition250available. Syntax-support definitions defined with {{define-for-syntax}}251and expansion-time expressions of the form {{(begin-for-syntax ...)}}252will be added to import libraries to make them available for exported253syntax. Note that these definitions will ruthlessly pollute the254toplevel namespace and so they should be used sparingly.255256257=== Predefined modules258259Import libraries for the following modules are initially260available outside of a module:261262 [module] scheme263 [module] (chicken base)264 [module] (chicken syntax)265266Every other module needs to be imported explicitly to have access to267its exported identifiers.268269270=== Examples of using modules271272Here is a silly little test module to demonstrate how modules273are defined and used:274275 ;; hello.scm276277 (module test (hello greet)278 (import scheme)279280 (define-syntax greet281 (syntax-rules ()282 ((_ whom)283 (begin284 (display "Hello, ")285 (display whom)286 (display " !\n") ) ) ) )287288 (define (hello)289 (greet "world") ) )290291The module {{test}} exports one value ({{hello}}) and one syntax292binding ({{greet}}). To use it in {{csi}}, the interpreter,293simply load and import it:294295 #;1> ,l hello.scm296 ; loading hello.scm ...297 ; loading /usr/local/lib/chicken/4/scheme.import.so ...298 #;1> (import test)299 #;2> (hello)300 Hello, world !301 #;3> (greet "you")302 Hello, you !303304The module can easily be compiled305306 % csc -s hello.scm307308and used in an identical manner:309310 #;1> ,l hello.so311 ; loading hello.so ...312 #;1> (import test)313 #;2> (hello)314 Hello, world !315 #;3> (greet "you")316 Hello, you !317318If you want to keep macro-definitions in a separate file, use import319libraries:320321 % csc -s hello.scm -j test322 % csc -s test.import.scm323324 #;1> ,l hello.so325 ; loading hello.so ...326 #;1> (import test)327 ; loading ./test.import.so ...328 #;2> (hello)329 Hello, world !330 #;3> (greet "you")331 Hello, you !332333If an import library (compiled or in source-form) is located334somewhere in the extensions-repository or include path, it335is automatically loaded on import. Otherwise you have to336load it manually:337338 #;1> ,l hello.so339 ; loading hello.so ...340 #;1> ,l test.import.so341 ; loading test.import.so ...342 #;1> (import test)343 #;2>344345Note that you must use import libraries if you compile code346that depends on other modules. The compiler will not execute347the modules that are referred to by compiled code, and thus348the binding information and exported syntax of the former349must be available separately.350351=== Example of compiling modules and linking them into an executable352353Here is a test module, in the file mymod.scm:354355<enscript highlight=scheme>356(module mymod (hello)357 (import scheme)358 (define (hello)359 (display "Hello, World, I'm in mymod!")360 (newline)))361</enscript>362363Here is the main module, in the file trymod.scm:364365<enscript highlight=scheme>366(module trymod ()367 (import scheme)368 (import mymod)369 (display "I'm in trymod!")370 (newline)371 (hello)372 (display "Now I'm back in trymod!")373 (newline))374</enscript>375376You can compile mymod.scm into a shared object and compile trymod.scm into an executable trymod that uses that shared object like this:377378 csc -s -J mymod.scm379 csc trymod.scm380381You can execute trymod and it will load the shared object mymod.so. When loading a shared382object, the CHICKEN runtime uses the libld API to obtain the entry point ("C_toplevel") to invoke top-level initialization code of the module (which also setups up global bindings, etc.). However, if you move the trymod executable to another directory, it won't be able to find mymod.so to load it. If you want include the object into the executable directly, it needs to have a unique entry point name, separate from any other entry point of other linked modules.383384To give the module a name, we pass the "-unit modulename" argument to csc, and the name of the module is added to the entry point, so the entry point for mymod would become "C_mymod_toplevel". Then the "-uses modulename" argument is passed to csc while compiling and linking trymod so it knows to use that entry point.385386To compile mymod.scm and trymod.scm and link them into the executable trymod, issue the following commands:387388 csc -c -J mymod.scm -unit mymod -o mymod.o389 csc -o trymod mymod.o -uses mymod trymod.scm390391This creates an executable that is dynamically linked against libchicken.so, but which includes the mymod.o object file directly.392393To create an executable that is statically linked, issue the following commands:394395 csc -c -static -J mymod.scm -unit mymod -o mymod.o396 csc -o trymod -static mymod.o -uses mymod trymod.scm397398If you later add another module you'd need to compile it similar to how mymod.scm is399compiled and add a "modulename.o -uses modulename" to the csc command that compiles trymod.scm.400401It is possible to use the csm program installed by the [[/egg/csm|csm egg]] to do this automatically. To produce a dynamically linked program you would do:402403 csm -program trymod404405To produce a statically linked program you would do:406407 csm -static -program trymod408409=== Functors410411A ''functor'' is a higher-order module that can be parameterized with412other modules. A functor defines the body of a module for a set of413argument modules and can be instantiated with concrete module names414specializing the code contained in the functor. This is best explained415with a silly and pointless example:416417<enscript highlight=scheme>418(functor (squaring-functor (M (multiply))) (square)419 (import scheme M)420 (define (square x) (multiply x x)))421</enscript>422423This defines a generic "squaring" operation that uses {{multiply}}, a424procedure (or macro!) exported by the as-yet-unknown module {{M}}. Now425let's instantiate the functor for a specific input module:426427<enscript highlight=scheme>428(module nums (multiply)429 (import scheme)430 (define (multiply x y) (* x y)))431432(module number-squarer = (squaring-functor nums))433434(import number-squarer)435(square 3) ===> 9436</enscript>437438We can easily instantiate the functor for other inputs:439440<enscript highlight=scheme>441(module stars (multiply)442 (import scheme)443 (define (list-tabulate n f)444 (let loop ((i 0))445 (if (= i n)446 '()447 (cons (f i) (loop (+ i 1))))))448 (define (multiply x y)449 (list-tabulate x (lambda _ (list-tabulate y (lambda _ '*))))))450451(module star-squarer = (squaring-functor stars))452453(import star-squarer)454(square 3) ===> ((* * *)455 (* * *)456 (* * *))457</enscript>458459So whenever you have a generic algorithm it can be packaged into a460functor and specialized for specific input modules. The instantiation461will check that the argument modules match the required signature,462{{(multiply)}} in the case above. The argument module must export at463least the signature given in the functor definition. You can use464{{define-interface}} to reduce typing and give a more meaningful name465to a set of exports.466467The general syntax of a functor definition looks like this:468469<syntax>(functor (FUNCTORNAME (ARGUMENTMODULE1 EXPORTS1) ...) FUNCTOREXPORTS BODY)</syntax>470471Defines a "functor", a parameterized module.472473This functor definition does not generate any code. This is done474by ''instantiating'' the functor for specific input modules:475476<enscript highlight=scheme>477(module MODULENAME = (FUNCTORNAME MODULENAME1 ...))478</enscript>479480Inside {{BODY}}, references to {{ARGUMENTMODULE}} will be replaced by481the corresponding {{MODULENAME}} argument. The instantiation expands482into the complete functor-code {{BODY}} and as such can be considered483a particular sort of macro-expansion. Note that there is no484requirement that a specific export of an argument-module must be485syntax or non-syntax - it can be syntax in one instantiation and a486procedure definition in another.487488{{ARGUMENTMODULE}} may also be a list of the form {{(ALIAS DEFAULT)}}489to allow specifying a default- or optional functor argument in case490the instanation doesn't provide one. Optional functor491arguments may only be followed by non-optional functor arguments.492493The common case of using a functor with a single argument module494that is not used elsewhere can be expressed in the following way:495496<enscript highlight=scheme>497(module NAME = FUNCTORNAME BODY ...)498</enscript>499500which is the same as501502<enscript highlight=scheme>503(begin504 (module _NAME * BODY ...)505 (module NAME = (FUNCTORNAME _NAME)))506</enscript>507508Since functors exist at compile time, they can be stored in509import-libraries via {{-emit-import-library FUNCTORNAME}} or510{{-emit-all-import-libraries}} (see [[Using the compiler]] for more511information about this). That allows you to import functors for later512instantiation. Internally, a functor-definition also defines a module513with the same name, but importing this module has no effect. It also514has no runtime code, so it is sufficient to merely {{import}} it (as515opposed to using {{require-extension}} or one of its variants, which516also loads the run-time part of a module).517518Note that functor-instantiation creates a complete copy of the519functor body.520521=== current-module522523<macro>(current-module)</macro>524525This will expand to a symbol which matches the current module's name526when used inside a module. If not inside a module (i.e., at527toplevel), this expands to {{#f}}.528529530---531Previous: [[Interface to external functions and variables]]532533Next: [[Types]]