~ 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}} module to do anything useful. To access any30of the non-standard macros and procedures, import the {{(chicken base)}}31module.3233CHICKEN's module system has the following features:3435* Separation of compile/expansion-time and run-time code is provided, which allows cross compilation36* Supports batch-compilation of separate compilation units37* Imports can be lexically scoped38* Parameterized modules are supported3940At toplevel and outside of a module, the initially available bindings41are everything that is exported from the [[Module scheme|scheme]],42[[Module (chicken base)|(chicken base)]] and43[[Module (chicken syntax)|(chicken syntax)]] modules.444546==== module4748<macro>(module NAME (EXPORT ...) BODY ...)</macro>49<macro>(module NAME (EXPORT ...) FILENAME)</macro>50<macro>(module NAME * BODY ...)</macro>51<macro>(module NAME = (FUNCTORNAME MODULENAME1 ...))</macro>52<macro>(module NAME = FUNCTORNAME BODY ...)</macro>5354Defines a module with the name {{NAME}}, a set of exported bindings and55a contained sequence of toplevel expressions that are evaluated in an56empty syntactical environment.5758{{NAME}} and {{FUNCTORNAME}} should be symbols or lists of symbols and59integers, where {{(foo bar baz)}} is equivalent to {{foo.bar.baz}}.6061{{(EXPORT ...)}} should be an export-specification which holds a list62of identifiers to be exported from the module and which should be63visible when imported into another module or the toplevel64environment. {{EXPORT}} may have any of the following forms:6566{{IDENTIFIER}} names a value- or syntax binding to be exported.6768{{(IDENTIFIER1 ...)}} or {{(syntax: IDENTIFIER1 ...)}} exports69{{IDENTIFIER1}} (which should name a macro) and also arranges for the70remaining identifiers in the list to be visible as value bindings in the expansion of71the macro (this is a hint to the module expander to export bindings72referenced by syntax-definitions which make use of them, but which73would normally be internal to the module - which gives more74opportunities for optimization).7576{{(interface: INTERFACENAME)}} adds all exports defined for the given77interface to be added to the list of exported identifiers of this78module.7980As a special case, specifying {{*}} instead of an export-list will81export all definitions. As another special case, the export-list may82be a symbol naming an interface.8384When the {{BODY}} consists of a single string, it is treated85like {{(include FILENAME)}}.8687{{(module NAME = (FUNCTORNAME MODULENAME1 ...))}} instantiates88a ''functor'' (see below for information about functors).8990{{(module NAME = FUNCTORNAME BODY ...)}} is a special form of91''functor instantiation'' where the {{BODY}} implements a module92satisfying a single functor argument to {{FUNCTORNAME}}.9394Nested modules, modules not at toplevel (i.e. local modules) or95mutually recursive modules are not supported.9697When compiled, the module information, including exported syntax98is stored in the generated binary and available when loading99it into interpreted or compiled code. Note that this is different100to normal syntax (outside of module declarations), which are normally101not exported from compiled code.102103Note that the module system is only a device for controlling the104mapping of identifiers to value or syntax bindings. Modules do not105instantiate separate environments that contain their own bindings, as106do many other module systems. Redefinition or assignment of value or107syntax bindings will modify the original, imported definition.108109Syntax expansions may result in module-definitions, but must be110at toplevel.111112113==== export114115<macro>(export EXPORT ...)</macro>116117Allows augmenting module-exports from inside the module-body.118{{EXPORT}} is if the same form as an export-specifier in a119{{module}} export list. An export must precede its first occurrence120(either use or definition).121122If used outside of a module, then this form does nothing.123124==== export/rename125126<macro>(export/rename (NAME EXPORT) ...)</macro>127128Allows augmenting module-exports from inside the module-body.129Each argument should be a two-element list containing the name130of the local value- or syntax-definition (NAME) and the name under which the131definition should be exported (EXPORT).132133If used outside of a module, then this form does nothing.134135==== import136137<macro>(import IMPORT ...)</macro>138139Imports module bindings into the current syntactical environment.140The visibility of any imported bindings is limited to the current141module, if used inside a module-definition, or to the current142compilation unit, if compiled and used outside of a module.143144Importing a module will also load or link its associated library when145needed.146147{{IMPORT}} may be a module name or an ''import specifier'', where a148module name is either a symbol or a list of symbols and integers.149An {{IMPORT}} defines a set of bindings that are to be made visible150in the current scope.151152===== only153154 [import specifier] (only IMPORT IDENTIFIER ...)155156Only import the listed value- or syntax bindings from the set given157by {{IMPORT}}.158159===== except160161 [import specifier] (except IMPORT IDENTIFIER ...)162163Remove the listed identifiers from the import-set defined by {{IMPORT}}.164165===== rename166167 [import specifier] (rename IMPORT (OLD1 NEW1) ...)168169Renames identifiers imported from {{IMPORT}}.170171===== prefix172173 [import specifier] (prefix IMPORT SYMBOL)174175Prefixes all imported identifiers with {{SYMBOL}}.176177==== import-syntax178179<macro>(import-syntax IMPORT ...)</macro>180181Similar to {{import}} but only import syntactic definitions such as182macros, as well as identifiers, but does not load or link the library183containing the module.184185==== import-for-syntax186187<macro>(import-for-syntax IMPORT ...)</macro>188189Similar to {{import}}, but imports exported bindings of a module into190the environment in which macro transformers are evaluated.191192Note: currently this isn't fully correct - value bindings are still193imported into the normal environment because a separate import194environment for syntax has not been implemented (syntactic bindings195are kept separate correctly).196197==== import-syntax-for-syntax198199<macro>(import-syntax-for-syntax IMPORT ...)</macro>200201Combination of {{import-syntax}} and {{import-for-syntax}}. Loads202syntactic definitions and valinside the environment in which macro203transformers are evaluated but do not load the associated library.204205==== reexport206207<macro>(reexport IMPORT ...)</macro>208209Imports {{IMPORT ...}} and automatically exports all imported identifiers.210This can be used to build ''compound modules'': modules that just extend211other modules:212213<enscript hightlight=scheme>214(module r4rs ()215 (import scheme (chicken module))216 (reexport217 (except scheme218 dynamic-wind values call-with-values eval scheme-report-environment219 null-environment interaction-environment)))220</enscript>221222223=== define-interface224225<macro>(define-interface INTERFACENAME (EXPORT ...))</macro>226227Defines an ''interface'', a group of exports that can be used in228module-definitions using the {{(interface: INTERFACE)}} syntax.229See the definition of {{module}} above for an explanation of230{{EXPORT}} specifications.231232Interface names use a distinct global namespace. Interfaces defined233inside modules are not visible outside of the module body.234235236=== import libraries237238''import libraries'' allow the syntactical (compile-time)239and run-time parts of a compiled module to be separated into a normal240compiled file and a shared library that only contains macro definitions241and module information. This reduces the size of executables and242simplifies compiling code that uses modules for a different architecture243than the machine the compiler is executing on (i.e. "cross" compilation).244245By using the {{emit-import-library}} compiler-option or declaration,246a separate file is generated that only contains syntactical information247(including macros) for a module. {{import}} will automatically find and248load an import library for a currently unknown module, if the import-249library is either in the extension repository or the current include250path. Interpreted code251can simply load the import library to make the module-definition252available. Syntax-support definitions defined with {{define-for-syntax}}253and expansion-time expressions of the form {{(begin-for-syntax ...)}}254will be added to import libraries to make them available for exported255syntax. Note that these definitions will ruthlessly pollute the256toplevel namespace and so they should be used sparingly.257258259=== Predefined modules260261Import libraries for the following modules are initially262available outside of a module:263264 [module] scheme265 [module] (chicken base)266 [module] (chicken syntax)267268Every other module needs to be imported explicitly to have access to269its exported identifiers.270271272=== Examples of using modules273274Here is a silly little test module to demonstrate how modules275are defined and used:276277 ;; hello.scm278279 (module test (hello greet)280 (import scheme)281282 (define-syntax greet283 (syntax-rules ()284 ((_ whom)285 (begin286 (display "Hello, ")287 (display whom)288 (display " !\n") ) ) ) )289290 (define (hello)291 (greet "world") ) )292293The module {{test}} exports one value ({{hello}}) and one syntax294binding ({{greet}}). To use it in {{csi}}, the interpreter,295simply load and import it:296297 #;1> ,l hello.scm298 ; loading hello.scm ...299 ; loading /usr/local/lib/chicken/4/scheme.import.so ...300 #;1> (import test)301 #;2> (hello)302 Hello, world !303 #;3> (greet "you")304 Hello, you !305306The module can easily be compiled307308 % csc -s hello.scm309310and used in an identical manner:311312 #;1> ,l hello.so313 ; loading hello.so ...314 #;1> (import test)315 #;2> (hello)316 Hello, world !317 #;3> (greet "you")318 Hello, you !319320If you want to keep macro-definitions in a separate file, use import321libraries:322323 % csc -s hello.scm -j test324 % csc -s test.import.scm325326 #;1> ,l hello.so327 ; loading hello.so ...328 #;1> (import test)329 ; loading ./test.import.so ...330 #;2> (hello)331 Hello, world !332 #;3> (greet "you")333 Hello, you !334335If an import library (compiled or in source-form) is located336somewhere in the extensions-repository or include path, it337is automatically loaded on import. Otherwise you have to338load it manually:339340 #;1> ,l hello.so341 ; loading hello.so ...342 #;1> ,l test.import.so343 ; loading test.import.so ...344 #;1> (import test)345 #;2>346347Note that you must use import libraries if you compile code348that depends on other modules. The compiler will not execute349the modules that are referred to by compiled code, and thus350the binding information and exported syntax of the former351must be available separately.352353=== Example of compiling modules and linking them into an executable354355Here is a test module, in the file mymod.scm:356357<enscript highlight=scheme>358(module mymod (hello)359 (import scheme)360 (define (hello)361 (display "Hello, World, I'm in mymod!")362 (newline)))363</enscript>364365Here is the main module, in the file trymod.scm:366367<enscript highlight=scheme>368(module trymod ()369 (import scheme)370 (import mymod)371 (display "I'm in trymod!")372 (newline)373 (hello)374 (display "Now I'm back in trymod!")375 (newline))376</enscript>377378You can compile mymod.scm into a shared object and compile trymod.scm into an executable trymod that uses that shared object like this:379380 csc -s -J mymod.scm381 csc trymod.scm382383You can execute trymod and it will load the shared object mymod.so. When loading a shared384object, 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.385386To 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.387388To compile mymod.scm and trymod.scm and link them into the executable trymod, issue the following commands:389390 csc -c -J mymod.scm -unit mymod -o mymod.o391 csc -o trymod mymod.o -uses mymod trymod.scm392393This creates an executable that is dynamically linked against libchicken.so, but which includes the mymod.o object file directly.394395To create an executable that is statically linked, issue the following commands:396397 csc -c -static -J mymod.scm -unit mymod -o mymod.o398 csc -o trymod -static mymod.o -uses mymod trymod.scm399400If you later add another module you'd need to compile it similar to how mymod.scm is401compiled and add a "modulename.o -uses modulename" to the csc command that compiles trymod.scm.402403It 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:404405 csm -program trymod406407To produce a statically linked program you would do:408409 csm -static -program trymod410411=== Functors412413A ''functor'' is a higher-order module that can be parameterized with414other modules. A functor defines the body of a module for a set of415argument modules and can be instantiated with concrete module names416specializing the code contained in the functor. This is best explained417with a silly and pointless example:418419<enscript highlight=scheme>420(functor (squaring-functor (M (multiply))) (square)421 (import scheme M)422 (define (square x) (multiply x x)))423</enscript>424425This defines a generic "squaring" operation that uses {{multiply}}, a426procedure (or macro!) exported by the as-yet-unknown module {{M}}. Now427let's instantiate the functor for a specific input module:428429<enscript highlight=scheme>430(module nums (multiply)431 (import scheme)432 (define (multiply x y) (* x y)))433434(module number-squarer = (squaring-functor nums))435436(import number-squarer)437(square 3) ===> 9438</enscript>439440We can easily instantiate the functor for other inputs:441442<enscript highlight=scheme>443(module stars (multiply)444 (import scheme)445 (define (list-tabulate n f)446 (let loop ((i 0))447 (if (= i n)448 '()449 (cons (f i) (loop (+ i 1))))))450 (define (multiply x y)451 (list-tabulate x (lambda _ (list-tabulate y (lambda _ '*))))))452453(module star-squarer = (squaring-functor stars))454455(import star-squarer)456(square 3) ===> ((* * *)457 (* * *)458 (* * *))459</enscript>460461So whenever you have a generic algorithm it can be packaged into a462functor and specialized for specific input modules. The instantiation463will check that the argument modules match the required signature,464{{(multiply)}} in the case above. The argument module must export at465least the signature given in the functor definition. You can use466{{define-interface}} to reduce typing and give a more meaningful name467to a set of exports.468469The general syntax of a functor definition looks like this:470471<syntax>(functor (FUNCTORNAME (ARGUMENTMODULE1 EXPORTS1) ...) FUNCTOREXPORTS BODY)</syntax>472473Defines a "functor", a parameterized module.474475This functor definition does not generate any code. This is done476by ''instantiating'' the functor for specific input modules:477478<enscript highlight=scheme>479(module MODULENAME = (FUNCTORNAME MODULENAME1 ...))480</enscript>481482Inside {{BODY}}, references to {{ARGUMENTMODULE}} will be replaced by483the corresponding {{MODULENAME}} argument. The instantiation expands484into the complete functor-code {{BODY}} and as such can be considered485a particular sort of macro-expansion. Note that there is no486requirement that a specific export of an argument-module must be487syntax or non-syntax - it can be syntax in one instantiation and a488procedure definition in another.489490{{ARGUMENTMODULE}} may also be a list of the form {{(ALIAS DEFAULT)}}491to allow specifying a default- or optional functor argument in case492the instanation doesn't provide one. Optional functor493arguments may only be followed by non-optional functor arguments.494495The common case of using a functor with a single argument module496that is not used elsewhere can be expressed in the following way:497498<enscript highlight=scheme>499(module NAME = FUNCTORNAME BODY ...)500</enscript>501502which is the same as503504<enscript highlight=scheme>505(begin506 (module _NAME * BODY ...)507 (module NAME = (FUNCTORNAME _NAME)))508</enscript>509510Since functors exist at compile time, they can be stored in511import-libraries via {{-emit-import-library FUNCTORNAME}} or512{{-emit-all-import-libraries}} (see [[Using the compiler]] for more513information about this). That allows you to import functors for later514instantiation. Internally, a functor-definition also defines a module515with the same name, but importing this module has no effect. It also516has no runtime code, so it is sufficient to merely {{import}} it (as517opposed to using {{require-extension}} or one of its variants, which518also loads the run-time part of a module).519520Note that functor-instantiation creates a complete copy of the521functor body.522523=== current-module524525<macro>(current-module)</macro>526527This will expand to a symbol which matches the current module's name528when used inside a module. If not inside a module (i.e., at529toplevel), this expands to {{#f}}.530531532---533Previous: [[Interface to external functions and variables]]534535Next: [[Types]]