Note: This is taken from the Chicken Wiki, where a more recent version could be available.
A simple but flexible module system, based on Standard ML modules and Taylor Campbells "lexmod" module system.
This extension is obsolete. Use lexmod instead.
A structure is an object containing named values. A signature is a set of names and (optionally) constraint-predicates which specify an interface that a structure must satisfy. A functor is a structure parameterized over other structures. A module is a structure or functor.
Note that this facility does not work at together with the syntax-case extension.
<macro>(define-signature SIGNATURE SIG ...)</macro>
Declares an interface. SIG should be a symbol or a signature name, or a list of the form (NAME PREDICATE)
<macro>(structure (EXPORT ...) DEFINITION ...)</macro>
Creates and returns a structure containing DEFINITION ... DEFINITION should be one of the following forms:
(define (NAME ...) ...) (define NAME VALUE) (define-values (NAME ...) VALUES)
The definitions are executed sequentially, and the value of each definition is only available in subsequent definitions (but may be referred to by earlier definitions, with the same restrictions as local defines). Definitions may be interspersed by normal expressions.
The defined names will only be available in this structure unless exported.
EXPORT ... should be a list of export-specifications conforming to the following grammar:
EXPORT = (export NAME ...) | SIGNATURE
If (EXPORT ...) is empty, the structure exports all defined bindings. If (EXPORT ...) is not empty, then the structure does only export bindings, for which export-specifications are given. If a signature defines a constraint-predicate and an exported value does not satisfy the predicate an error is signalled. An error is also signalled, when a structure does not define an exported binding.
<procedure>(structure? X [EXPORT ...])</procedure>
Returns #t, if X is a structure or functor, or #f otherwise. If EXPORT is supplied, then must be a form following the grammer for EXPORT given above. One or more instances of an EXPORT form may be supplied.
<procedure>(compound-structure STRUCTURE ...)</procedure>
Returns a new structure that shares all bindings given in STRUCTURE .... If multiple structures export a identically named value, an error is signalled.
<macro>(functor ((VAR STRUCTURE IMPORT ...) ...) (EXPORT ...) DEFINITION ...)</macro>
Similar to structure, but the definitions are evaluated in a lexical environment, where the variables VAR ... are bound to structures given in STRUCTURE .... Each argument structure may be constrained by an import-specification, of the following grammar:
IMPORT = (import NAME ...) | SIGNATURE
If no constraint is given for an argument structure, then all exported bindings of that structure are imported.
All imported bindings of the argument structures are lexically visible inside the DEFINITIONS ....
<macro>(define-functor (NAME STRUCTURE-ARGUMENT ...) (EXPORT ...) DEFINITION ...)</macro>
A convenient syntax for procedures that create functors. STRUCTURE-ARGUMENT should be a variable or a list of the form (VAR IMPORT ...).
(define-functor (make-f x (y my-signature)) () ...)
Is equivalent to
(define (make-f x y) (functor ((x x) (y y my-signature)) () ...) )
<macro>(in-structure STRUCTURE (IMPORT ...) BODY ...)</macro>
Evaluates BODY ... with an environment that binds the values from STRUCTURES and given in IMPORT ... to lexically visible variables. IMPORT should be of the form:
IMPORT = (import NAME ...) | SIGNATURE
<procedure>(open STRUCTURE ...)</procedure>
Imports all exported bindings from the argument structures as toplevel variables.
<procedure>(structure-ref STRUCTURE NAME)</procedure>
Locates the exported binding of the symbol NAME in STRUCTURE and returns its value. If STRUCTURE does not export name, an error is signalled.
<example> <init>(use structures)</init> <expr> (define-signature arith-signature zero sum diff prod recip quo)
(structure (arith-signature) (define zero '(0 . 0)) (define (sum x y) (cons (+ (car x) (car y)) (+ (cdr x) (cdr y)))) (define (diff x y) (cons (- (car x) (car y)) (- (cdr x) (cdr y)))) (define (prod x y) (cons (- (* (car x) (car y)) (* (cdr x) (cdr y))) (+ (* (car x) (cdr y)) (* (car y) (cdr x))) ) ) (define (recip x) (let ([t (+ (* (car x) (car x)) (* (cdr x) (cdr x)))]) (cons (/ (car x) t) (/ (- (cdr x) t))) ) ) (define (quo x) (prod x (recip x))) ) )
(structure (arith-signature) (define zero 0) (define sum +) (define diff -) (define prod *) (define recip /) (define quo /) ) )
(in-structure simple ((import sum))
(print (sum 33 44)))
(in-structure complex ((import sum))
(print (sum '(10 . 1) '(33 . 2))) )
</expr> <output>(43 . 3)</output> <expr> (define-functor (squarer (s arith-signature)) ((export square))
(define (square n) (prod n n) ) )
(define simple-squarer (squarer simple)) (define complex-squarer (squarer complex))
(print ((structure-ref simple-squarer 'square) 9)) </expr> <output>81</output> <expr>(print ((structure-ref complex-squarer 'square) '(3 . 2)))</expr> <output>(5 . 12)</output> <expr> (open simple-squarer) (print (square 10)) </expr> <output>100</output> </example>
Copyright (c) 2003, Felix L. Winkelmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.