In this issue, we’ll take a look at an interesting pattern of passing multiple arguments to a function and use it to implement a recursive sum algorithm.
Example
Consider the following example:
sub f($a, *@b) { say "Head: $a"; say "Tail: @b[]"; } f(42, 43, 44);
The signature of the function has two elements: a scalar $a
and a slurpy array @b
. When you call f
with three parameters, the first one goes to $a
, and the rest land in @b
.
The program prints:
$ raku sub.raku Head: 42 Tail: 43 44
Recursive sum
Let us apply the pattern from the example to a program that recursively computes the sum of the elements of an array of numbers:
multi sub rsum($head) { $head } multi sub rsum($head, *@rest) { $head + rsum(|@rest) } say rsum(10, 20, 30, 40, 50); # 150
There are no assignments here, so this program is a perfect example of programming in a functional style in Raku.
We have two versions of the rsum
functions here. One needs a single value, and the second one accepts additional (but required) array. While there are more than one element in the data list, the second version of the function is run. On the last iteration, a single elements remains, and thus the simpler version of the function is executed. The sum of a single element is the element itself. In the output, you get the desired sum.
* * *
Find the code of this issue on GitHub and browse for more Raku Pearls.
> the second one accepts additional (but required) array
This is actually incorrect: a slurpy array is considered an optional parameter. The reason your example works, is that the other candidate (without the slurpy array) is *narrower* in the `count` attribute of the signature (1 versus Inf for the slurpy candidate).
Observe:
$ raku -e ‘sub foo($a,*@b) {dd $a, @b }; foo 42’
42
Array element = []