Motivation
I want to write an auxiliary function (brief auxf
) for testing the output of another function that evaluates its body repeatedly using Pause
in between evaluations.
This auxiliary function ideally must return a different value each time it is evaluated; those values need not be sequential but it's helpful if they are monotonic and deterministic.
The idea is to have a sense of what the output should be and juxtaposed it to the actual output of the function being tested in order to discern what branches get executed repeatedly etc.
Proposed approach
Now, what I could come up with was an auxf
inspired by what I think generators are supposed to do in Python or what the iota operator does for Go constants.
Briefly, I figured that a function that increases its output value by a certain delta for every successive evaluation would be ideal for this type of situation.
After doing some (soul) searching I managed to combine this amazing post with that piece of info from the documentation (first example in the Applications section) to obtain counter
(please note that auxf
above and faux
below are not related):
Module[{i = 0, reset, faux, invldoptval},
reset[] := (i = 0;);
counter::invldoptval = "Invalid option value '`1`'. Expected boolean.";
Options[counter] = {"Reset" -> False};
counter[args___] := faux[args];
faux[args___, OptionsPattern[counter]] := Module[{resetQ = OptionValue["Reset"]},
If[resetQ, reset[], i++, Message[counter::invldoptval, resetQ]]
]
]
Example
An example:
counter/@Range[5]
{0, 1, 2, 3, 4}
Resetting the counter
:
counter["Reset"->True]
counter[]
counter[]
0 1
Evaluating counter
with a wrong option value like in
counter["Reset"->None]
counter[]
produces a message
Invalid option value 'None'. Expected boolean. 2
Question
- Is there another idiomatic way to achieve a similar result as
counter
?- Are there any problems with this approach?
- Can you think of other use cases for this piece of code?
Thanks!
counter
does; the question is "is there better way to achieve the same effect thatcounter
delivers?" (perhaps I should've incorporated 2 and 3 in 1); as far as the title is concerned would you be so kind as to explain on what level you experience the disconnect? I wasn't aware closures were possible in MA and whatcounter
does is it "[...]create[s] closure" (link) $\endgroup$ – user42582 Jul 18 '18 at 12:56counter
though; hopefully after I digest UnevaluatedExpressions.nb I'll figure it out; thanks for the pointer it is really appreciated $\endgroup$ – user42582 Jul 24 '18 at 12:09