~ 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