Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop Raku collapsing a list containing a single list?

Tags:

raku

i've got a function, into which i want to be able to pass a list of lists, like in this artificial example:

sub print_lists(@input) {
    .say for @input
}

my @list_of_two_lists = ((1, 2), (3, 4)); 
print_lists(@list_of_two_lists);

this gives the following output, as expected:

(1, 2)
(3, 4)

but if i do this:

my @list_of_one_list = ((1, 2)); 
print_lists(@list_of_one_list);

i get this output:

1
2

i.e. it flattens the list containing one list of two elements, into a single list of two elements.

what am i doing wrong? what do i need to do if i want to be able to pass in a list containing a single list?

like image 547
Hives Avatar asked Nov 10 '21 19:11

Hives


People also ask

How to pull out individual elements from a list using Raku?

Individual elements can be pulled out of a list using a subscript. The first element of a list is at index number zero: Variables in Raku whose names bear the @ sigil are expected to contain some sort of list-like object. Of course, other variables may also contain these objects, but @ -sigiled variables always do, and are expected to act the part.

Can We have infinite lists in raku?

These are called sequences, which are of type Seq. As it so happens, loops return Seq s. So, it is fine to have infinite lists in Raku, just so long as you never ask them for all their elements.

What is itemization in raku list handling?

This is actually one of the trickiest parts of Raku list handling to get a firm understanding of. First, be aware that because itemization in Arrays is assumed, it essentially means that $ (…) s are being put around everything that you assign to an array, if you do not put them there yourself.

What is an array scalar in raku?

Raku will automatically type-check values and create Scalars to contain them when Arrays are initialized, assigned to, or constructed. This is actually one of the trickiest parts of Raku list handling to get a firm understanding of.


Video Answer


1 Answers

This behavior is a consequence of two Raku features, both of which are worth knowing.

The first is the Single Argument Rule. It's important enough to be worth reading the docs on, but the key takeaway is that when you pass a single list (as you do in with @list_of_one_list) constructs like for will iterate over each item in the list rather than over the list as a single item. In this case, that means iterating over the two items in the list, 1, and 2.

At this point, you might be thinking "but @list_of_one_list didn't have two items in it – it had one item: the list (1, 2)". But that's because we haven't gotten to the second point to understand: In Raku ( and ) are not what makes something a list. Instead, using the , operator is what constructs a list. This can take a tad bit of getting used to, but it's what allows Raku to treat parentheses as optional in many places that other languages require them.

To see this second point in action, I suggest you check out how .raku prints out your @list_of_lists. Compare:

my @list_of_one_list = ((1, 2));
say @list_of_one_list;  # OUTPUT: «[1, 2]»
my @list-of-one-list = (1, 2),;
say @list-of-one-list;  # OUTPUT: «[(1, 2)]»

And that's all the info you need to answer your question: simply add a , when you build your list of one list.

I hope that helped :)

like image 147
codesections Avatar answered Oct 22 '22 22:10

codesections