~ chicken-core (chicken-5) ef1aee77610668c3a8a344e2a8795e8e3fa9dbab


commit ef1aee77610668c3a8a344e2a8795e8e3fa9dbab
Author:     felix <felix@z.(none)>
AuthorDate: Tue Mar 22 14:50:45 2011 +0100
Commit:     felix <felix@z.(none)>
CommitDate: Tue Mar 22 14:50:45 2011 +0100

    added functor example

diff --git a/manual/Modules b/manual/Modules
index 4e67b944..a63e9531 100644
--- a/manual/Modules
+++ b/manual/Modules
@@ -357,12 +357,54 @@ A ''functor'' is a higher-order module that can be parameterized with
 other modules. A functor defines the body of a module for a set or
 argument modules and can be instantiated with concrete module names
 specializing the code contained in the functor. This is best explained
-with an example:
+with a silly and pointless example:
 
 <enscript highlight=scheme>
-XXX need example here...
+(functor (squaring-functor (M (multiply))) (square)
+  (import scheme M)
+  (define (square x) (multiply x x)))
 </enscript>
 
+This defines a generic "squaring" operation that uses {{multiply}}, a
+procedure (or macro!) exported by the as-yet-unknown module {{M}}. Now
+let's instantiate the functor for a specific input module:
+
+<enscript highlight=scheme>
+(module nums (multiply)
+  (import scheme)
+  (define (multiply x y) (* x y)))
+
+(module number-squarer = (squaring-functor nums))
+
+(import number-squarer)
+(square 3)                ===>  9
+</enscript>
+
+We can easily instantiate the functor for other inputs:
+
+<enscript highlight=scheme>
+(module stars (multiply)
+  (import scheme)
+  (use srfi-1)
+  (define (multiply x y) 
+    (list-tabulate x (lambda _ (list-tabulate y (lambda _ '*))))))
+
+(module star-squarer = (squaring-functor stars))
+
+(import star-squarer)
+(square 3)                ===>  ((* * *)
+                                 (* * *)
+                                 (* * *))
+</enscript>
+
+So whenever you have a generic algorithm it can be packaged into a
+functor and specialized for specific input modules.  The instantiation
+will check that the argument modules match the required signature,
+{{(multiply)}} in the case above.  The argument module must export at
+least the signature given in the functor definition. You can use
+{{define-interface}} to reduce typing and give a more meaningful name
+to a set of exports.
+
 The general syntax of a functor definition looks like this:
 
 <enscript highlight=scheme>
@@ -384,13 +426,17 @@ 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
-function definition in another.
+procedure definition in another.
 
 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.
+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).
 
 
 ---
Trap