Guifa was unhappy with $xml.elements returning a list with one undefined element if there are no child nodes. That led me to the conclusion that Nil is only halve Empty .

Let’s consider this piece of code.

sub nilish() { Nil }; for nilish() { say 'oi‽' } my $nil := nilish(); for $nil { say 'still oi‽' } sub no-return() { } for no-return() { say 'even more oi‽' } sub return-a-list( --> List:D ) { Nil } for return-a-list() { say 'Should this happen?' } # OUTPUT: # oi‽ # still oi‽ # even more oi‽ # Should this happen?

We are iterating over the special container-reset-value called Nil because there is no container to reset. Since for binds to its arguments it binds to Nil . A type object, even a very special one as Nil, is a single item which is treated as a list with one element by for .



We can solve this problem by a multi sub that turn unreasonable values into the empty list.

multi sub undefined-to-empty(Nil) { Empty } multi sub undefined-to-empty(@a where all @a.map(!*.defined)) { Empty } multi sub undefined-to-empty(\item) { item } for undefined-to-empty(Nil) { say 'nothing happens' } for undefined-to-empty((Any,)) { say 'nothing happens' }

By adding a candidate that checks if there are only undefined values in a list we can also solve guifa`s problem.



This is of cause just a shim. The real solution is to stop turning null into Nil in native bindings. If you write a sub that has to return a list but can’t either fail or return Empty if there is nothing to return. To help avoid that mistake in the future I filed #2721.

If it looks empty or sounds emtpy or tastes emtpy make it Empty !