Hi,
> In the book Programming Paradigms with Mathematica
> http://library.wolfram.com/infocenter/MathSource/1847/
> in the notebook Hw21.nb there is following function:
>
> Clear[makeCounter];
> makeCounter::usage="makeCounter[] returns a message-driven function
> which manipulates a \"hidden\" counter variable. The initial value
> of the counter variable may be set via an optional argument to
> makeCounter (default is 0). Valid messages for the function are
> \"++\" (increment), \"--\" (decrement), \"value\", and \"reset\".
> For example, ctr = makeCounter[100]; ctr[\"value\"] returns 100.";
>
> makeCounter[
> defaultValue_Integer:0
> ] :=
> Module[
> { counter = defaultValue,
> changeCounter
> },
> changeCounter[msg_String:"++"] :=
> Switch[msg,
> "++",
> counter = counter + 1; counter,
> "--",
> counter = counter - 1; counter,
> "value",
> counter,
> "reset",
> counter = defaultValue; counter,
> _,
> Print["Unknown message to counter:", msg];
> counter
> ];
> changeCounter
> ];
>
> ctr = makeCounter[100]
> ctr["value"]
> ctr["++"]
>
> gives as output
>
> changeCounter$723
> 100
> 101
>
> Where can I find more explanation of this type of "message-driven function"?
I think the tricky part here is not that the function is message driven,
but how it uses the Module variables so you can create many independent
instances of counter functions. From the documentation you will find
that the symbols in the list in the first argument of Module are meant
to be local variables. So usually after the body of Module has finished,
they will 'disappear'. It is an additional feature of Module that you
can return local variables or expressions containing local variables,
which is done here. These (local!) variables will then survive, even
though they are now 'out of scope'. On the Mathematica side you can
learn more about this by searching the documentation for Module and
lexical scoping and probably also Unique. From a computer science point
of view (which I am no expert for), I think this special behavior of
Module is used here to mimic something that is known as a 'closure' in
other programming languages, so you might want to search the web (or CS
books) for 'closures' and learn whether my mentioning of them in this
context was correct...
hth,
albert