Symmetric code
While reading Arne`s solution for Challenge #140.2, I spotted a nested simple loop.
for 1 .. $i -> $ii # [3]
{
for 1 .. $j -> $jj # [3]
{
@result.push: $ii * $jj; # [4]
}
}
In Raku-land, we don’t really need simple loops. Often we can .map
or use a hyper operator. I had the nagging feeling this is also the case for simple nested loop. A good night’s sleep later I remembered that “X” marks the spot.
The cross-product-operator X
is implemented with 2 nesting loops and returns a list of lists. In Raku we construct lists with infix:<,>
.
use Test;
is-deeply ((1,2) X, (3,4)), ((1,2) X (3,4)), 'yep!';
So we are actually calling X,
. If we replace infix:<,>
with infix:<*>
, we get what Arne did without the temporary container.
for [2, 3, 4; 3, 3, 6; 200, 300, 40; 0, 0, 0] -> [$i, $j, $k] {
put ((1..$i) X* (1..$j)).sort[$k - 1];
CATCH { when X::OutOfRange { warn „Sorry, I can't find position $k in the multiplication table of $i and $j.“ } }
}
I wonder if there are more cases, where we could look at the implementation of a high-level language feature, to spot places worthy of replacing wordy code with a single operator call.
-
November 29, 2021 at 19:282021.48 Raku at FOSDEM 2022 – Rakudo Weekly News