A Raku riddle
While thinking about DataKinds blog post I came up with a most peculiar riddle. It goes as follows:
Name something that when removed is still defined but never existed.
The answer is an Array element whereby the Array got default values.
my @a is default('fill') = 1,2,3;
say @a[5]:exists; # False
@a = @a[5]:delete;
say @a[5].defined; # True
say @a[5]:exists; # False
How many elements got such an Array and when will iteration end?
say @a.elems; # 3
.print for @a; # 123
It has 3 elements and we can iterate over them. What makes perfect sense. However, if we judge by definedness for looping it will be infinite.
while @a[$++] -> $_ { .say } # will not stop
Is this an infinite list then? It can not run out of elements so if we believe the docs about infix:<Z>
it should never stop the zipping.
use v6;
my @a is default('‽') = 1,2,3;
my @b = <a b c d e>;
say @a Z @b;
# OUTPUT: ((1 a) (2 b) (3 c))
I tried to convince Z
to behave as desired to no avail. In the process I learned how to set the default value of a container long after its declaration.
my @a := Array.new;
{
use nqp;
my $descriptor = nqp::getattr(@a.VAR, Array, '$!descriptor');
my $a = $descriptor.set_default('‽');
}
say @a[1];
# OUTPUT: ‽
Rakudo does a lot with iterators. Since they are an implementation detail, we can’t easily build our own. That’s not really a problem because the zip operator is clever enough to DWIM.
my @a = 1,2,3;
my @b = <a b c d e>;
say ((|@a, |('‽' xx *)) Z (|@b, |('‽' xx *)))[^(@a.elems max @b.elems)];
# OUTPUT: ((1 a) (2 b) (3 c) (‽ d) (‽ e))
I believe that is what DataKinds was looking for.
-
June 29, 2020 at 23:182020.26 Cloud Gone – Rakudo Weekly News
-
July 6, 2020 at 16:532020.27 Advanced Beginning – Rakudo Weekly News