Factorial, being a classical task for drilling algorithms, is a great example to demonstrate the features of Raku. You can find a number of different implementations in the corresponding section of my book Using Raku.
Let us update the code so that it caches the already calculated values.
I am using multi-functions to distinguish between zero and non-zero arguments:
multi sub postfix:<!>(0) { 1 } multi sub postfix:<!>($n) { $n * ($n - 1)! }
Let us add a state variable to the second variant of the function so that it remembers the values and returns it immediately if it is already known:
multi sub postfix:<!>(0) { 1 } multi sub postfix:<!>($n) { state %factorial; %factorial{$n} //= $n * ($n - 1)! }
Notice how you can assign the new value if needed and return the result in a single line without any if
constructs. Also don’t forget the the last computed value is returned by the function.
As a homework, add some printing instructions to see how the function fills up the cache and test it on a few randomly ordered numbers:
say 5!; say 7!; say 4!;
Also take a look at the Memoize module.
Huh. “is cached” is no longer part of the core language?
It is said to be experimental: https://docs.raku.org/syntax/cached