Home > Raku > A Raku riddle

## 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.

Categories: Raku