Recursion with action blocks

fmcpma

Member
Hello.

I was experimenting with action blocks and I noticed how all their variables (input, work and output) have a default value and not just a current value. Could this mean that, contrary to macro variables, action block variables are reinstantiated from their default value each time a block is called? That would allow for straightforward recursion!

With that in mind, I tried to write simple blocks to calculate Factorial (yes, I know there is the FACT() function, which is much faster and doesn't crash if n gets a little higher, but what the hell) and the Fibonacci sequence, which are basic examples of recursion. And yes! It works. I checked the log and could see that, each time a block gets a nested call, its variables change value from their defaults (0 in these cases), not from their current value in the outer call – that is, new instances are created. Cool! (Did I just write that?)

Maybe everybody already new this but I didnt't, so here are my two functions. Enjoy.

P.S. – What isn't shown here is where the output.result variable goes when the blocks call themselves. Well, in the case of Factorial, it goes into work.prev_res; in Fibonacci there are two calls to itself and, obviously, in the first call output.result goes into work.prev_res1 and in the second it goes into work.prev_res2.

P.P.S. – I also wrote short descriptions for both functions/blocks but they weren't included by Share as Image. So I'll copy them here:

Factorial: Calculates the factorial of n for n >= 0. If n < 0 signals an error as -1.

Fibonacci: Calculates the n.th member of the Fibonacci sequence for n >= 1, where the first two members are 1,2. If n < 1 signals an error as -1.

P.P.P.S. – Actually, there was a slight bug in the Fibonacci function, though it made no difference to the resulting value. In the calls to itself, the variables work.prev_n2 and work.prev_n1, which are assigned to input.n, are the other way around: work.prev_n1 should be used in the first call and work.prev_n2 in the second.



Factorial.png



Fibonacci.png
 
Last edited:

fmcpma

Member
Hello again.

Today I bring you new versions of both functions / action blocks presented above.

The new versions have the following improvements over the original ones:

1. They now use decimal variables (instead of integers) for the results, which allow for much greater values of these, i.e., much higher values of n can be used now. For the Fibonacci function n can now go all the way to 1475, where before 19 was the upper limit. This change also stops the function from crashing with high values of n. Factorial allows a maximum n of 170, which is the same as for the built-in FACT() function. Of course, these limits are caused by the fact that higher values of n produce results which just won't fit into decimal variables – much less into integers. When the n used is too high, the returned result will be -1, as to signal the error, the same way as values that are too low already produced a -1 result.

2. Both functions now store the result for a value of n which had not been used before in a global array and they will fetch the result from there the next time that value of n is used, which, of course, produces immediate results the second time around. Therefore, one could start by calling the functions with n = 170 and n = 1475, for Factorial and Fibonacci, respectively, which could take a while, depending on the processor in one's device, but from then on results would be instantaneous. The arrays must be global because changes to local variables in action blocks don't persist upon exit.

3. Best of all, there is now a nice little caller macro for each function, in order to allow experimentation of the functions!

I've uploaded both functions (along with their respective caller macros) to the Templates section and their links, for Factorial and Fibonacci, respectively, are:



Thank you for your attention and enjoy.
 
Last edited:
Top