BrowserREPL-button-tip-on BrowserREPL-button-tip-off

EditButtonTip 2026-02-08

class List

Sequence of values

my class List does Iterable does Positional { }
Code

List stores items sequentially and potentially lazily.

Indexes into lists and arrays start at 0 by default.

You can assign to list elements if they are containers. Use Arrays to have every value of the list stored in a container.

List implements Positional and as such provides support for subscripts.

Immutability§

Lists are immutable objects, i.e., neither the number of elements in a list nor the elements themselves can be changed. Thus, it is not possible to use operations that change the list structure itself such as shift, unshift, push, pop, splice and binding.

(1, 2, 3).shift;      # Error Cannot call 'shift' on an immutable 'List'
(1, 2, 3).unshift(0); # Error Cannot call 'unshift' on an immutable 'List'
(1, 2, 3).push(4);    # Error Cannot call 'push' on an immutable 'List'
(1, 2, 3).pop;        # Error Cannot call 'pop' on an immutable 'List'
(1, 2, 3)[0]:delete;  # Error Cannot remove elements from a List
(1, 2, 3)[0] := 0;    # Error Cannot use bind operator with this left-hand side
(1, 2, 3)[0] = 0;     # Error Cannot modify an immutable Int
Code

A List doesn't containerize its elements, but if any element happens to be inside a Scalar container then the element's contents can be replaced via an assignment.

my $a = 'z';
my $list = ($a, $, 'b');

say $list[0].VAR.^name; # OUTPUT: «Scalar␤», containerized
say $list[1].VAR.^name; # OUTPUT: «Scalar␤», containerized
say $list[2].VAR.^name; # OUTPUT: «Str␤», non-containerized

$list[0] = 'a'; # OK!
$list[1] = 'c'; # OK!
$list[2] = 'd'; # Error: Cannot modify an immutable List
Code

Items, flattening and sigils§

In Raku, assigning a List to a scalar variable does not lose information. The difference is that iteration generally treats a list (or any other list-like object, like a Seq or an Array) inside a scalar as a single element.

my $s = (1, 2, 3);
for $s { }      # one iteration
for $s.list { } # three iterations

my $t = [1, 2, 3];
for $t { }      # one iteration
for $t.list { } # three iterations

my @a = 1, 2, 3;
for @a { }      # three iterations
for @a.item { } # one iteration
Code

This operation is called itemization or putting in an item context. .item does the job for objects, as well as $( ... ) and, on array variables, $@a.

Lists generally don't interpolate (flatten) into other lists, except when they are in list context and the single argument to an operation such as append:

my $a = (1, 2, 3);
my $nested = ($a, $a);  # two elements

my $flat = $nested.map({ .Slip });  # six elements, with explicit Slip

my @b = <a b>;
@b.append: $a.list;     # The array variable @b has 5 elements, because
                        # the list $a is the sole argument to append

say @b.elems;           # OUTPUT: «5␤»

my @c = <a b>;
@c.append: $a.list, 7;  # The array variable @c has 4 elements, because
                        # the list $a wasn't the only argument and thus
                        # wasn't flattened by the append operation

say @c.elems;           # OUTPUT: «4␤»

my @d = <a b>;
@d.append: $a;          # The array variable @d has 3 elements, because
                        # $a is in an item context and as far as append is
                        # concerned a single element

say @d.elems;           # OUTPUT: «3␤»
Code

The same flattening behavior applies to all objects that do the Iterable role, notably Hashes:

my %h = a => 1, b => 2;
my @b = %h;   say @b.elems;     # OUTPUT: «2␤»
my @c = %h, ; say @c.elems;     # OUTPUT: «1␤»
my @d = $%h;  say @d.elems;     # OUTPUT: «1␤»
Code

Slurpy parameters (*@a) flatten non-itemized sublists:

sub fe(*@flat) { @flat.elems }
say fe(<a b>, <d e>);           # OUTPUT: «4␤»
say fe(<a b>, <d e>.item);      # OUTPUT: «3␤»
Code

The empty list is created with (). Smartmatching against the empty list will check for the absence of elements.

my @a;
for @a, @a.list, @a.Seq -> \listoid {
    say listoid ~~ ()
}
# OUTPUT: «True␤True␤True␤»
Code

Retrieving values from an empty list will always return Nil:

say ()[33.rand]; # OUTPUT: «Nil␤»
Code

Coercion to Bool also indicates if the List got any elements.

my @a;
say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[0 False False]␤»
@a.push: 42;
say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[1 True True]␤»
say 'empty' unless @a;        # no output
Code

Methods§

method ACCEPTS§

multi method ACCEPTS(List:D: $topic)
Code

If $topic is an Iterable, returns True or False based on whether the contents of the two Iterables match. A Whatever element in the invocant matches anything in the corresponding position of the $topic Iterable. A HyperWhatever matches any number of any elements, including no elements:

say (1, 2, 3)       ~~ (1,  *, 3);  # OUTPUT: «True␤»
say (1, 2, 3)       ~~ (9,  *, 5);  # OUTPUT: «False␤»
say (1, 2, 3)       ~~ (   **, 3);  # OUTPUT: «True␤»
say (1, 2, 3)       ~~ (   **, 5);  # OUTPUT: «False␤»
say (1, 3)          ~~ (1, **, 3); # OUTPUT: «True␤»
say (1, 2, 4, 5, 3) ~~ (1, **, 3); # OUTPUT: «True␤»
say (1, 2, 4, 5, 6) ~~ (1, **, 5); # OUTPUT: «False␤»
say (1, 2, 4, 5, 6) ~~ (   **   ); # OUTPUT: «True␤»
say ()              ~~ (   **   ); # OUTPUT: «True␤»
Code

In addition, returns False if either the invocant or $topic is a lazy Iterable, unless $topic is the same object as the invocant, in which case True is returned.

If $topic is not an Iterable, returns the invocant if the invocant has no elements or its first element is a Match object (this behavior powers m:g// smartmatch), or False otherwise.

routine list§

multi        list(+list)
multi method list(List:D:)
Code

The method just returns the invocant self. The subroutine adheres to the single argument rule: if called with a single argument that is a non-itemized Iterable it returns a List based on the argument's iterator; otherwise it just returns the argument list.

For example:

my $tuple = (1, 2);         # an itemized List
put $tuple.list.raku;       # OUTPUT: «(1, 2)␤»
put list($tuple).raku;      # OUTPUT: «($(1, 2),)␤»
put list(|$tuple).raku;     # OUTPUT: «(1, 2)␤»
Code

The last statement uses the prefix:<|> operator to flatten the tuple into an argument list, so it is equivalent to:

put list(1, 2).raku;        # OUTPUT: «(1, 2)␤»
Code

There are other ways to list the elements of an itemized single argument. For example, you can decontainerize the argument or use the @ list contextualizer:

put list($tuple<>).raku;    # OUTPUT: «(1, 2)␤»
put list(@$tuple).raku;     # OUTPUT: «(1, 2)␤»
Code

Note that converting a type object to a list may not do what you expect:

put List.list.raku;         # OUTPUT: «(List,)␤»
Code

This is because the .list candidate accepting a type object as the invocant is provided by Any. That candidate returns a list with one element: the type object self. If you're developing a collection type whose type object should be a valid representation of an empty collection, you may want to provide your own candidate for undefined invocants or override the Any: candidates with an "only" method. For example:

my class LinkedList {
    has $.value;            # the value stored in this node
    has LinkedList $.next;  # undefined if there is no next node

    method values( --> Seq:D) {
        my $node := self;
        gather while $node {
            take $node.value;
            $node := $node.next;
        }
    }

    method list( --> List:D) {
        self.values.list;
    }
}

my LinkedList $nodes;       # an empty linked list
put $nodes.list.raku;       # OUTPUT: «()␤»
Code

routine elems§

sub    elems($list --> Int:D)
method elems(List:D: --> Int:D)
Code

Returns the number of elements in the list.

say (1,2,3,4).elems; # OUTPUT: «4␤»
Code

routine end§

sub    end($list --> Int:D)
method end(List:D: --> Int:D)
Code

Returns the index of the last element.

say (1,2,3,4).end; # OUTPUT: «3␤»
Code

routine keys§

sub    keys($list --> Seq:D)
method keys(List:D: --> Seq:D)
Code

Returns a sequence of indexes into the list (e.g., 0...(@list.elems-1)).

say (1,2,3,4).keys; # OUTPUT: «(0 1 2 3)␤»
Code

routine values§

sub    values($list --> Seq:D)
method values(List:D: --> Seq:D)
Code

Returns a sequence of the list elements, in order.

say (1,2,3,4).^name;        # OUTPUT: «List␤»
say (1,2,3,4).values.^name; # OUTPUT: «Seq␤»
Code

routine kv§

sub    kv($list --> Seq:D)
method kv(List:D: --> Seq:D)
Code

Returns an interleaved sequence of indexes and values. For example

say <a b c>.kv; # OUTPUT: «(0 a 1 b 2 c)␤»
Code

routine pairs§

sub    pairs($list --> Seq:D)
method pairs(List:D: --> Seq:D)
Code

Returns a sequence of pairs, with the indexes as keys and the list values as values.

say <a b c>.pairs;   # OUTPUT: «(0 => a 1 => b 2 => c)␤»
Code

routine antipairs§

method antipairs(List:D: --> Seq:D)
Code

Returns a Seq of pairs, with the values as keys and the indexes as values, i.e. the direct opposite to pairs.

say <a b c>.antipairs;  # OUTPUT: «(a => 0 b => 1 c => 2)␤»
Code

routine invert§

method invert(List:D: --> Seq:D)
Code

Assumes every element of the List is a Pair. Returns all elements as a Seq of Pairs where the keys and values have been exchanged. If the value of a Pair is an Iterable, then it will expand the values of that Iterable into separate pairs.

my $l = List.new('a' => (2, 3), 'b' => 17);
say $l.invert;   # OUTPUT: «(2 => a 3 => a 17 => b)␤»
Code

routine join§

sub    join($separator, *@list)
method join(List:D: $separator = "")
Code

Treats the elements of the list as strings by calling .Str on each of them, interleaves them with $separator and concatenates everything into a single string.

Example:

say join ', ', <a b c>;             # OUTPUT: «a, b, c␤»
Code

The method form also allows you to omit the separator:

say <a b c>.join;               # OUTPUT: «abc␤»
Code

Note that the method form does not flatten sublists:

say (1, <a b c>).join('|');     # OUTPUT: «1|a b c␤»
Code

The subroutine form behaves slurpily, flattening all arguments after the first into a single list:

say join '|', 1, <a b c>;       # OUTPUT: «1|a|b|c␤»
Code

In this case, the list <a b c> is slurped and flattened, unlike what happens when join is invoked as a method.

If one of the elements of the list happens to be a Junction, then join will also return a Junction with concatenation done as much as possible:

say ("a"|"b","c","d").join;     # OUTPUT: «any(acd,bcd)␤»
Code

routine map§

multi method map(\SELF: &block)
multi        map(&code, +values)
Code

Examples applied to lists are included here for the purpose of illustration.

For a list, it invokes &code for each element and gathers the return values in a sequence and returns it. This happens lazily, i.e. &code is only invoked when the return values are accessed.Examples:

say ('hello', 1, 22/7, 42, 'world').map: { .^name } # OUTPUT: «(Str Int Rat Int Str)␤»
say map *.Str.chars, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(5 1 8 2 5)␤»
Code

map inspects the arity of the code object, and tries to pass as many arguments to it as expected:

sub b($a, $b) { "$a before $b" };
say <a b x y>.map(&b).join(', ');   # OUTPUT: «a before b, x before y␤»
Code

iterates the list two items at a time.

Note that map does not flatten embedded lists and arrays, so

((1, 2), <a b>).map({ .join(',')})
Code

passes (1, 2) and <a b> in turn to the block, leading to a total of two iterations and the result sequence "1,2", "a,b".

If &code is a Block loop phasers will be executed and loop control statements will be treated as in loop control flow. Please note that return is executed in the context of its definition. It is not the return statement of the block but the surrounding Routine. Using a Routine will also handle loop control statements and loop phasers. Any Routine specific control statement or phaser will be handled in the context of that Routine.

sub s {
my &loop-block = {
        return # return from sub s
    };
say 'hi';
(
1..3).map: &loop-block;
say 'oi‽' # dead code
};
s
# OUTPUT: «hi␤»
Code

method flatmap§

method flatmap(List:D: &code --> Seq:D)
Code

Convenience method, analogous to .map(&block).flat.

method gist§

multi method gist(List:D: --> Str:D)
Code

Returns the string containing the parenthesized "gist" of the List, listing up to the first 100 elements, separated by space, appending an ellipsis if the List has more than 100 elements. If List is-lazy, returns string '(...)'

put (1, 2, 3).gist;   # OUTPUT: «(1 2 3)␤»
put (1..∞).List.gist; # OUTPUT: «(...)␤»

put (1..200).List.gist;
# OUTPUT:
# (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
# 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
# 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
# 96 97 98 99 100 ...)
Code

routine grep§

sub    grep(Mu $matcher, *@elems, :$k, :$kv, :$p, :$v --> Seq:D)
method grep(List:D:  Mu $matcher, :$k, :$kv, :$p, :$v --> Seq:D)
Code

Returns a sequence of elements against which $matcher smartmatches. The elements are returned in the order in which they appear in the original list.

Examples:

say ('hello', 1, 22/7, 42, 'world').grep: Int;              # OUTPUT: «(1 42)␤»
say grep { .Str.chars > 3 }, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(hello 3.142857 world)␤»
Code

Note that if you want to grep for elements that do not match, you can use a none-Junction:

say <a b 6 d 8 0>.grep(none Int);           # OUTPUT: «(a b d)␤»
say <a b c d e f>.grep(none /<[aeiou]>/);   # OUTPUT: «(b c d f)␤»
Code

Another option to grep for elements that do not match a regex is to use a block:

say <a b c d e f>.grep({! /<[aeiou]>/})     # OUTPUT: «(b c d f)␤»
Code

The reason the example above works is because a regex in Boolean context applies itself to $_. In this case, ! boolifies the /<[aeiou]>/ regex and negates the result. Smartmatching against a Callable (in this case a Block) returns the value returned from that callable, so the boolified result of a regex is then used to decide whether the current value should be kept in the result of a grep.

The optional named parameters :k, :kv, :p, :v provide the same functionality as on slices:

  • k

Only return the index values of the matching elements in order.

  • kv

Return both the index and matched elements in order.

  • p

Return the index and the matched element as a Pair, in order.

  • v

Only return the matched elements (same as not specifying any named parameter at all).

Examples:

say ('hello', 1, 22/7, 42, 'world').grep: Int, :k;
# OUTPUT: «(1 3)␤»
say grep { .Str.chars > 3 }, :kv, 'hello', 1, 22/7, 42, 'world';
# OUTPUT: «(0 hello 2 3.142857 4 world)␤»
say grep { .Str.chars > 3 }, :p, 'hello', 1, 22/7, 42, 'world';
# OUTPUT: «(0 => hello 2 => 3.142857 4 => world)␤»
Code

routine first§

sub    first(Mu $matcher, *@elems, :$k, :$kv, :$p, :$end)
method first(List:D:  Mu $matcher?, :$k, :$kv, :$p, :$end)
Code

Returns the first item of the list which smartmatches against $matcher, returns Nil when no values match. The optional named parameter :end indicates that the search should be from the end of the list, rather than from the start.

Examples:

say (1, 22/7, 42, 300).first: * > 5;                  # OUTPUT: «42␤»
say (1, 22/7, 42, 300).first: * > 5, :end;            # OUTPUT: «300␤»
say ('hello', 1, 22/7, 42, 'world').first: Complex;   # OUTPUT: «Nil␤»
Code

The optional named parameters :k, :kv, :p provide the same functionality as on slices:

  • k

Return the index value of the matching element. Index is always counted from the beginning of the list, regardless of whether the :end named parameter is specified or not.

  • kv

Return both the index and matched element.

  • p

Return the index and the matched element as a Pair.

Examples:

say (1, 22/7, 42, 300).first: * > 5, :k;        # OUTPUT: «2␤»
say (1, 22/7, 42, 300).first: * > 5, :p;        # OUTPUT: «2 => 42␤»
say (1, 22/7, 42, 300).first: * > 5, :kv, :end; # OUTPUT: «(3 300)␤»
Code

In method form, the $matcher can be omitted, in which case the first available item (or last if :end is set) will be returned. See also head and tail methods.

method head§

multi method head(Any:D:) is raw
multi method head(Any:D: Callable:D $w)
multi method head(Any:D: $n)
Code

This method is directly inherited from Any, and it returns the first $n items of the list, an empty list if $n <= 0, or the first element with no argument. The version that takes a Callable uses a WhateverCode to specify all elements, starting from the first, but the last ones.

Examples:

say <a b c d e>.head ;     # OUTPUT: «a␤»
say <a b c d e>.head(2);   # OUTPUT: «(a b)␤»
say <a b c d e>.head(*-3); # OUTPUT: «(a b)␤»
Code

method tail§

multi method tail(List:D:)
multi method tail(List:D: $n --> Seq:D)
Code

Returns a Seq containing the last $n items of the list. Returns an empty Seq if $n <= 0. Defaults to the last element if no argument is specified. Throws an exception if the list is lazy.

Examples:

say <a b c d e>.tail(*-3);# OUTPUT: «(d e)␤»
say <a b c d e>.tail(2);  # OUTPUT: «(d e)␤»
say <a b c d e>.tail;     # OUTPUT: «e␤»
Code

In the first case, $n is taking the shape of a WhateverCode to indicate the number of elements from the beginning that will be excluded. $n can be either a Callable, in which case it will be called with the value 0, or anything else that can be converted to a number, in which case it will use that as the number of elements in the output Seq.

say <a b c d e>.tail( { $_ - 2 } ); # OUTPUT: «(c d e)␤»
Code

routine categorize§

multi method categorize()
multi method categorize(Whatever)
multi method categorize($test, :$into!, :&as)
multi method categorize($test, :&as)
multi        categorize($test, +items, :$into!, *%named )
multi        categorize($test, +items, *%named )
Code

These methods are directly inherited from Any; see Any.categorize for more examples.

This routine transforms a list of values into a hash representing the categorizations of those values according to $test, which is called once for every element in the list; each hash key represents one possible categorization for one or more of the incoming list values, and the corresponding hash value contains an array of those list values categorized by the $test, acting like a mapper, into the category of the associated key.

Note that, unlike classify, which assumes that the return value of the mapper is a single value, categorize always assumes that the return value of the mapper is a list of categories that are appropriate to the current value.

Example:

sub mapper(Int $i) returns List {
    $i %% 2 ?? 'even' !! 'odd',
    $i.is-prime ?? 'prime' !! 'not prime'
}
say categorize &mapper, (1, 7, 6, 3, 2);
# OUTPUT: «{even => [6 2], not prime => [1 6], odd => [1 7 3], prime => [7 3 2]}␤»
Code

routine classify§

multi method classify($test, :$into!, :&as)
multi method classify($test, :&as)
multi        classify($test, +items, :$into!, *%named )
multi        classify($test, +items, *%named )
Code

Transforms a list of values into a hash representing the classification of those values; each hash key represents the classification for one or more of the incoming list values, and the corresponding hash value contains an array of those list values classified into the category of the associated key. $test will be an expression that will produce the hash keys according to which the elements are going to be classified.

Example:

say classify { $_ %% 2 ?? 'even' !! 'odd' }, (1, 7, 6, 3, 2);
# OUTPUT: «{even => [6 2], odd => [1 7 3]}␤»
say ('hello', 1, 22/7, 42, 'world').classify: { .Str.chars };
# OUTPUT: «{1 => [1], 2 => [42], 5 => [hello world], 8 => [3.142857]}␤»
Code

It can also take :as as a named parameter, transforming the value before classifying it:

say <Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ });
# OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»
Code

This code is classifying by number of characters, which is the expression that has been passed as $test parameter, but the :as block lowercases it before doing the transformation. The named parameter :into can also be used to classify into a newly defined variable:

<Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ }, :into( my %words{Int} ) );
say %words; # OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»
Code

We are declaring the scope of %words{Int} on the fly, with keys that are actually integers; it gets created with the result of the classification.

method Bool§

method Bool(List:D: --> Bool:D)
Code

Returns True if the list has at least one element, and False for the empty list.

say ().Bool;  # OUTPUT: «False␤»
say (1).Bool; # OUTPUT: «True␤»
Code

method Str§

method Str(List:D: --> Str:D)
Code

Stringifies the elements of the list and joins them with spaces (same as .join(' ')).

say (1,2,3,4,5).Str; # OUTPUT: «1 2 3 4 5␤»
Code

method Int§

method Int(List:D: --> Int:D)
Code

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Int; # OUTPUT: «5␤»
Code

method Numeric§

method Numeric(List:D: --> Int:D)
Code

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Numeric; # OUTPUT: «5␤»
Code

method Capture§

method Capture(List:D: --> Capture:D)
Code

Returns a Capture where each Pair, if any, in the <List has been converted to a named argument (with the key of the Pair stringified). All other elements in the List are converted to positional arguments in the order they are found, i.e. the first non pair item in the list becomes the first positional argument, which gets index 0, the second non pair item becomes the second positional argument, getting index 1 etc.

my $list = (7, 5, a => 2, b => 17);
my $capture = $list.Capture;
say $capture.keys;                                # OUTPUT: «(0 1 a b)␤»
my-sub(|$capture);                                # OUTPUT: «7, 5, 2, 17␤»

sub my-sub($first, $second, :$a, :$b) {
    say "$first, $second, $a, $b"
}
Code

A more advanced example demonstrating the returned Capture being matched against a Signature.

my $list = (7, 5, a => 2, b => 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «True␤»

$list = (8, 5, a => 2, b => 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «False␤»
Code

routine pick§

multi        pick($count, *@list --> Seq:D)
multi method pick(List:D: $count --> Seq:D)
multi method pick(List:D: --> Mu)
multi method pick(List:D: Callable $calculate --> Seq:D)
Code

If $count is supplied: Returns $count elements chosen at random and without repetition from the invocant. If * is passed as $count, or $count is greater than or equal to the size of the list, then all elements from the invocant list are returned in a random sequence; i.e. they are returned shuffled.

In method form, if $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.pick;           # OUTPUT: «b␤»
say <a b c d e>.pick: 3;        # OUTPUT: «(c a e)␤»
say <a b c d e>.pick: *;        # OUTPUT: «(e d a b c)␤»
Code

As of the 2021.06 release of the Rakudo compiler, it is also possible to specify ** (aka HyperWhatever) as the count.

In that case, .pick will start picking again on the original list after it has been exhausted, again and again, indefinitely.

say <a b c>.pick(**).head(10);  # OUTPUT: «((a c b c a b b c a b))␤»
Code

routine roll§

multi        roll($count, *@list --> Seq:D)
multi method roll(List:D: $count --> Seq:D)
multi method roll(List:D: --> Mu)
Code

If $count is supplied: Returns a sequence of $count elements, each randomly selected from the list. Each random choice is made independently, like a separate die roll where each die face is a list element. If * is passed as $count returns a lazy, infinite sequence of randomly chosen elements from the original list.

If $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.roll;       # 1 random letter
say <a b c d e>.roll: 3;    # 3 random letters
say roll 8, <a b c d e>;    # 8 random letters

my $random-digits := (^10).roll(*);
say $random-digits[^15];    # 15 random digits
Code

routine eager§

multi method eager(List:D: --> List:D)
Code

Evaluates all elements in the List eagerly, and returns them as a List.

my  \ll = (lazy 1..5).cache;

say ll[];     # OUTPUT: «(...)␤»
say ll.eager  # OUTPUT: «(1 2 3 4 5)␤»
Code

routine reverse§

multi        reverse(*@list  --> Seq:D)
multi method reverse(List:D: --> Seq:D)
Code

Returns a Seq with the same elements in reverse order.

Note that reverse always refers to reversing elements of a list; to reverse the characters in a string, use flip.

Examples:

say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤»
say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»
Code

routine rotate§

multi        rotate(@list,  Int:D $n = 1 --> Seq:D)
multi method rotate(List:D: Int:D $n = 1 --> Seq:D)
Code

Returns a Seq with the list elements rotated to the left when $n is positive or to the right otherwise.

Examples:

say <a b c d e>.rotate(2);   # OUTPUT: (c d e a b)
say <a b c d e>.rotate(-1);  # OUTPUT: (e a b c d)
Code

Note: Before Rakudo release 2020.06 a new List was returned instead of a Seq.

routine sort§

multi        sort(*@elems      --> Seq:D)
multi        sort(&custom-routine-to-use, *@elems --> Seq:D)
multi method sort(List:D:      --> Seq:D)
multi method sort(List:D: &custom-routine-to-use  --> Seq:D)
Code

Sorts the list, smallest element first. By default infix:<cmp> is used for comparing list elements.

If &custom-routine-to-use is provided, and it accepts two arguments, it is invoked for pairs of list elements, and should return Order::Less, Order::Same or Order::More.

If &custom-routine-to-use accepts only one argument, the list elements are sorted according to custom-routine-to-use($a) cmp custom-routine-to-use($b). The return values of &custom-routine-to-use are cached, so that &custom-routine-to-use is only called once per list element.

Examples:

say (3, -4, 7, -1, 2, 0).sort;                  # OUTPUT: «(-4 -1 0 2 3 7)␤»
say (3, -4, 7, -1, 2, 0).sort: *.abs;           # OUTPUT: «(0 -1 2 3 -4 7)␤»
say (3, -4, 7, -1, 2, 0).sort: { $^b leg $^a }; # OUTPUT: «(7 3 2 0 -4 -1)␤»
Code

Additionally, if &custom-routine-to-use returns a List, elements will be sorted based upon multiple values with subsequent values in the List being used to break the tie if the comparison between the prior elements evaluate to Order::Same.

my @resistance = (
    %( first-name => 'Kyle',  last-name => 'Reese'  ),
    %( first-name => 'Sarah', last-name => 'Connor' ),
    %( first-name => 'John',  last-name => 'Connor' ),
);
.say for @resistance.sort: { .<last-name>, .<first-name> };

#`(
OUTPUT:
{first-name => John, last-name => Connor}
{first-name => Sarah, last-name => Connor}
{first-name => Kyle, last-name => Reese}
)
Code

This sorting can be based on characteristics of a single element:

say <ddd aaa bbb bb ccc c>.sort( {.chars, .Str} );
# OUTPUT: «(c bb aaa bbb ccc ddd)␤»
Code

In this case, elements of the array are sorted in ascending order according first to the string length (.chars) and second to the actual alphabetical order .Str) if the length is exactly the same.

Any number of criteria can be used in this:

say <01 11 111 2 20 02>.sort( { .Int, .comb.sum, .Str } );
# OUTPUT: «(01 02 2 11 20 111)␤»
Code

Calling the sort sub without any arguments has become a runtime error as of release 2022.07 of the Rakudo compiler:

sort;   # ERROR: «Must specify something to sort␤»
Code

As of release 2023.08 of the Rakudo compiler it is also possible to specify a :k named argument. This will cause the result to be a list of indices of the sorting process.

say <a c b d e>.sort(:k); # OUTPUT: «(0 2 1 3 4)␤»
say sort <a c b d e>, :k; # OUTPUT: «(0 2 1 3 4)␤»
Code

routine reduce§

multi method reduce(Any:D: &with)
multi        reduce (&with, +list)
Code

Returns a single "combined" value from a list of arbitrarily many values, by iteratively applying a routine which knows how to combine two values. In addition to the subroutine and the list, an initial value can be provided to initialize the reduction, which ends up being the return value if the list is empty. Thus reduce f, init, list combines the elements of the list from left to right, as is shown in the following pseudocode:

result0 = init
result1 = f(result0, list[0])
result2 = f(result1, list[1])
...
resultn = f(resultn-1, list[n-1])
Code

resultn is the final result for an n-element list.

say reduce &infix:<+>, (1, 2, 3); # OUTPUT: «6␤»
say (1, 2, 3).reduce: &infix:<+>; # OUTPUT: «6␤»
say reduce &max, (5, 9, 12, 1);   # OUTPUT: «12␤»
Code

If list contains just a single element, the operator is applied to that single element if possible; if not, it returns the element itself.

say reduce &infix:<->, (10,);     # OUTPUT: «10␤»
Code

When the list contains no elements, an exception is thrown, unless &with is an operator with a known identity value (e.g., the identity value of infix:<+> is 0). For this reason, you're advised to prefix the input list with an initial value (or explicit identity value):

my \strings = "One good string!", "And one another good string!";
say reduce { $^a ~ $^b }, '', |strings;               # like strings.join

my \numbers = 1, 2, 3, 4, 5;
say reduce { $^a > $^b ?? $^a !! $^b }, 0, |numbers; # like numbers.max

sub count-and-sum-evens( (Int \count, Int \sum), Int \x ) {
    x %% 2 ?? (count+1, sum+x) !! (count, sum)
}

say reduce &count-and-sum-evens, (0, 0), |numbers;    # OUTPUT: «(2 6)␤»
Code

In the last example, since reduce only supports one initial value we use a List with two values, which is by itself a single value. The count-and-sum-evens subroutine takes two positional values: a List of two Ints and an Int, and return a List storing the count and sum of the even integers accumulated.

If &with is the code object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).reduce(&infix:<OP>) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81
(2,3,4).reduce(&infix:<**>).lsb.say;  # OUTPUT: «81␤»
(2**(3**4)).lsb.say;                  # OUTPUT: «81␤»
(2**3**4).lsb.say;                    # OUTPUT: «81␤»

# Subtract 4 from -1, because 2 minus 3 is -1
(2,3,4).reduce(&infix:<->).say;       # OUTPUT: «-5␤»
((2-3)-4).say;                        # OUTPUT: «-5␤»
(2-3-4).say;                          # OUTPUT: «-5␤»
Code

Since reducing with an infix operator is a common thing to do, the reduction metaoperator [ ] provides a syntactic shortcut. Thus, instead of passing the operator's code object to reduce, just pass the operator directly to [ ]. To use a user-defined subroutine instead, provide an additional layer of square brackets around the subroutine's code object:

say [*] (1, 2, 3, 4);       # OUTPUT: «24␤»
say [min] (4, 2, 1, 3);     # OUTPUT: «1␤»

sub mult { $^a * $^b };
say [[&mult]] (1, 2, 3, 4); # OUTPUT: «24␤»
Code

Semantically, all the following do the same thing:

my \numbers = 1, 2, 3, 4, 5;
say reduce { $^a + $^b }, 0, |numbers;
say reduce * + *, 0, |numbers;
say reduce &[+], numbers; # operator does not need explicit identity value
say [+] numbers;
Code

Since reduce is an implicit loop that iterates over with its reducing subroutine, it responds to next, last and redo statements inside &with:

sub last-after-seven { last if $^a > 7; $^a + $^b };
say (2, 3, 4, 5).reduce: &last-after-seven; # OUTPUT: «9␤»
Code

Whether reduce accumulates the elements starting from the left or from the right depends on the operator. In the functional programming world, this operation is generally called a fold. With a right-associative operator it is a right fold, otherwise (and usually) it is a left fold. In Raku, you can specify the associativity of an operator with the is assoc trait.

sub infix:<foo>($a, $b) is assoc<right> { "($a, $b)" }
say [foo] 1, 2, 3, 4; # OUTPUT: «(1, (2, (3, 4)))␤»

sub infix:<bar>($a, $b) is assoc<left> { "($a, $b)" }
say [bar] 1, 2, 3, 4; # OUTPUT: «(((1, 2), 3), 4)␤»
Code

Practical example 1: In this example, we generate a random-ish math formula (e.g., "(4 + ((3 * x) + 11) / 6))") using reduce.

my @ops = [Z] (<+ - * />, 1..20)».roll(4);

say ('x', |@ops).reduce: -> $formula, [$op, $number] {
    Bool.pick ?? "($formula $op $number)"
              !! "($number $op $formula)"
}
Code

Practical example 2: Suppose we have a polynomial represented as a list of integer coefficients, c[n-1], c[n-2], ..., c[0], where c[i] is the coefficient of xi. We can evaluate it using map and reduce as follows:

sub evaluate(List:D \c where c.all ~~ Int, Rat:D \x --> Rat:D) {
    my \xi = (c.elems ^... 0).map: -> \i { x ** i }; # [x^(n-1), ..., x^0]
    my \axi = [+] c Z* xi;                           # [c[n-1]*x^(n-1), ..., c[*]x^0]
    [+] axi;                                         # sum of axi
}

my \c = 2, 3, 1;       # 2x² + 3x + 1
say evaluate c, 3.0;   # OUTPUT: «28␤»
say evaluate c, 10.0;  # OUTPUT: «231␤»
Code

routine produce§

multi        produce(&with, *@values)
multi method produce(List:D: &with)
Code

Generates a list of all intermediate "combined" values along with the final result by iteratively applying a function which knows how to combine two values.

If @values contains just a single element, a list containing that element is returned immediately. If it contains no elements, an exception is thrown, unless &with is an operator with a known identity value.

If &with is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).produce(&[OP]) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81
[2,3,4].produce(&[**]).say;        # OUTPUT: «(4 81 2417851639229258349412352)␤»
say produce &[**], (2,3,4);        # OUTPUT: «(4 81 2417851639229258349412352)␤»
say [\**] (2,3,4);                 # OUTPUT: «(4 81 2417851639229258349412352)␤»

# Subtract 4 from -1, because 2 minus 3 is -1
[2,3,4].produce(&[-]).say;         # OUTPUT: «(2 -1 -5)␤»
say produce &[-], (2,3,4);         # OUTPUT: «(2 -1 -5)␤»
say [\-] (2,3,4);                  # OUTPUT: «(2 -1 -5)␤»
Code

A triangle metaoperator [\ ] provides a syntactic shortcut for producing with an infix operator:

# The following all do the same thing...
my @numbers = (1,2,3,4,5);
say produce { $^a + $^b }, @numbers;
say produce * + *, @numbers;
say produce &[+], @numbers; # operator does not need explicit identity
say [\+] @numbers;          # most people write it this way
Code

The visual picture of a triangle [\ is not accidental. To produce a triangular list of lists, you can use a "triangular comma":

[\,] 1..5;
# (
# (1)
# (1 2)
# (1 2 3)
# (1 2 3 4)
# (1 2 3 4 5)
# )
Code

Since produce is an implicit loop, it responds to next, last and redo statements inside &with:

say (2,3,4,5).produce: { last if $^a > 7; $^a + $^b }; # OUTPUT: «(2 5 9)␤»
Code

routine combinations§

multi        combinations($from, $of = 0..*             --> Seq:D)
multi method combinations(List:D: Int() $of             --> Seq:D)
multi method combinations(List:D: Iterable:D $of = 0..* --> Seq:D)
Code

Returns a Seq with all $of-combinations of the invocant list. $of can be a numeric Range, in which case combinations of the range of item numbers it represents will be returned (i.e. 2.6 .. 4 will return 2-, 3-, and 4-item combinations). Otherwise, $of is coerced to an Int.

.say for <a b c>.combinations: 2;
# OUTPUT:
# (a b)
# (a c)
# (b c)
Code

Above, there are three possible ways to combine the 2-items lists from the original list, which is what we receive in the output. See permutations if you want permutations instead of combinations.

With Range argument, we get both three 2-item combinations and one 3-item combination:

.say for <a b c>.combinations: 2..3;
# OUTPUT:
# (a b)
# (a c)
# (b c)
# (a b c)
Code

If $of is negative or is larger than there are items in the given list, an empty list will be returned. If $of is zero, a 1-item list containing an empty list will be returned (there's exactly 1 way to pick no items).

The subroutine form is equivalent to the method form called on the first argument ($from), with the exception that if $from is not an Iterable, it gets coerced to an Int and combinations are made from a Range constructed with 0..^$from instead:

.say for combinations 3, 2
# OUTPUT:
# (0 1)
# (0 2)
# (1 2)
Code

Note: some implementations may limit the maximum value of non-Iterable $from. On Rakudo, 64-bit systems have a limit of 2³¹-1 and 32-bit systems have a limit of 2²⁸-1.

routine permutations§

multi        permutations(Int()    $from --> Seq:D)
multi        permutations(Iterable $from --> Seq:D)
multi method permutations(List:D:        --> Seq:D)
Code

Returns all possible permutations of a list as a Seq of lists:

.say for <a b c>.permutations;
# OUTPUT:
# (a b c)
# (a c b)
# (b a c)
# (b c a)
# (c a b)
# (c b a)
Code

permutations treats all elements as unique, thus (1, 1, 2).permutations returns a list of 6 elements, even though there are only three distinct permutations, due to first two elements being the same.

The subroutine form behaves the same as the method form, computing permutations from its first argument $from. If $from is not an Iterable, coerces $from to an Int and picks from a Range constructed with 0..^$from:

.say for permutations 3;
# OUTPUT:
# (0 1 2)
# (0 2 1)
# (1 0 2)
# (1 2 0)
# (2 0 1)
# (2 1 0)
Code

routine rotor§

method rotor(+@cycle, Bool() :$partial --> Seq:D)
Code

Returns a sequence of lists, where each sublist is made up of elements of the invocant.

In the simplest case, @cycle contains just one integer, in which case the invocant list is split into sublists with as many elements as the integer specifies. If :$partial is True, the final chunk is included even if it doesn't satisfy the length requirement:

say ('a'..'h').rotor(3).join('|');              # OUTPUT: «a b c|d e f␤»
say ('a'..'h').rotor(3, :partial).join('|');    # OUTPUT: «a b c|d e f|g h␤»
Code

If the element of @cycle is a Pair instead, the key of the pair specifies the length of the return sublist, and the value the gap between sublists; negative gaps produce overlap:

say ('a'..'h').rotor(2 => 1).join('|');         # OUTPUT: «a b|d e|g h␤»
say ('a'..'h').rotor(3 => -1).join('|');        # OUTPUT: «a b c|c d e|e f g␤»
Code

If @cycle contains more than element, rotor cycles through it to find the number of elements for each sublist:

say ('a'..'h').rotor(2, 3).join('|');           # OUTPUT: «a b|c d e|f g␤»
say ('a'..'h').rotor(1 => 1, 3).join('|');      # OUTPUT: «a|c d e|f␤»
Code

Combining multiple cycles and :partial also works:

say ('a'..'h').rotor(1 => 1, 3 => -1, :partial).join('|');
# OUTPUT: «a|c d e|e|g h␤»
Code

See this blog post for more elaboration on rotor.

From language version 6.e onward, there is also a subroutine rotor (early implementation exists in Rakudo compiler 2022.02+):

multi rotor(Int:D $batch, \thing, Bool() :$partial --> Seq:D)
Code
multi rotor(**@cycle, \thing, Bool() :$partial --> Seq:D)
Code

Technically, having a slurpy **@cycle before the positional parameter \thing is not possible, so the actual signature of the second multi is different in Rakudo. In practice, however, things work as you would expect from the signatures given here:

say rotor(3, 'a'..'h').join('|');             # OUTPUT: «a b c|d e f␤»
say rotor(3, 'a'..'h', :partial).join('|');   # OUTPUT: «a b c|d e f|g h␤»
say rotor(2 => 1, 'a'..'h').join('|');        # OUTPUT: «a b|d e|g h␤»
say rotor(3 => -1, 'a'..'h').join('|');       # OUTPUT: «a b c|c d e|e f g␤»
say rotor(1 => 1, 3 => -1, 'a'..'h', :partial).join('|');
# OUTPUT: «a|c d e|e|g h␤»
Code

method batch§

multi method batch(Int:D $batch --> Seq)
multi method batch(Int:D :$elems --> Seq)
Code

Returns a sequence of lists, wherein each list with the exception of the last one is guaranteed to comprise a number of elements equal to the batch size specified by $batch or $elems, respectively. If the invocant has a number of elements that is not an integer multiple of the batch size, the last list in the returned sequence will contain any remaining elements and thus have fewer than $batch or $elems elements. Accordingly, .batch($batch) is shorthand for .rotor($batch, :partial).

routine cross§

sub cross(+@e, :&with --> Seq:D)
Code

Computes the cross-product of two or more lists or Iterables. This returns a sequence of lists where the first item in each list is an item from the first iterable, the second is from the second given iterable, etc. Every item will be paired with every other item in all the other lists.

say cross(<a b c>, <d e f>).map(*.join).join(",")
# OUTPUT: «ad,ae,af,bd,be,bf,cd,ce,cf␤»
Code

The cross routine has an infix synonym as well, named X.

say (<a b c> X <d e f>).map(*.join).join(",")
# output is the same as the previous example
Code

If the optional with parameter is passed, it is used as a reduction operation to apply to each of the cross product items.

say cross([1, 2, 3], [4, 5, 6], :with(&infix:<*>)).join(",");
# OUTPUT: «4,5,6,8,10,12,12,15,18␤»
Code

The X operator can be combined with another operator as a metaoperator to perform a reduction as well:

say ([1, 2, 3] X* [4, 5, 6]).join(",")
# same output as the previous example
Code

routine zip§

sub zip(+@e, :&with --> Seq:D)
Code

Builds a 'list of lists', returned as a sequence, from multiple input lists or other Iterables.

zip iterates through each of the input lists synchronously, 'Zipping' them together, so that elements are grouped according to their input list index, in the order that the lists are provided.

say zip(<a b c>, <d e f>, <g h i>);
# OUTPUT: «((a d g) (b e h) (c f i))␤»
Code

zip has an infix synonym, the Z operator.

say <a b c> Z <d e f> Z <g h i>;                   # same output
Code

zip can provide input to a for loop :

for <a b c> Z <d e f> Z <g h i> -> [$x,$y,$z] {say ($x,$y,$z).join(",")}
# OUTPUT: «a,d,g␤b,e,h␤c,f,i␤»
Code

, or more succinctly:

say .join(",") for zip <a b c>, <d e f>, <g h i>;  # same output
Code

Note, that if the input lists have an unequal number of elements, then zip terminates once the shortest input list is exhausted, and trailing elements from longer input lists are discarded.

say <a b c> Z <d e f m n o p> Z <g h i>;
# ((a d g) (b e h) (c f i))
Code

In cases where data clipping is possible, but undesired, then consider using roundrobin instead of zip.

The optional with parameter will additionally reduce the zipped lists. For example, the following multiplies corresponding elements together to return a single list of products.

.say for zip <1 2 3>, [1, 2, 3], (1, 2, 3), :with(&infix:<*>);
# OUTPUT: «1␤8␤27␤»
Code

The Z form can also be used to perform reduction by implicitly setting the with parameter with a metaoperator :

.say for <1 2 3> Z* [1, 2, 3] Z* (1, 2, 3);        # same output
Code

routine roundrobin§

sub roundrobin(+list-of-lists --> Seq)
Code

Builds a 'list of lists', returned as a sequence, from multiple input lists or other Iterables. roundrobin returns an identical result to that of zip, except when the input lists are allowed to have an unequal number of elements.

say roundrobin <a b c>, <d e f>, <g h i>;
# OUTPUT: «((a d g) (b e h) (c f i))␤»

say .join(",") for roundrobin([1, 2], [2, 3], [3, 4]);
# OUTPUT: «1,2,3␤2,3,4␤»
Code

roundrobin does not terminate once one or more of the input lists become exhausted, but proceeds until all elements from all lists have been processed.

say roundrobin <a b c>, <d e f m n o p>, <g h i j>;
# OUTPUT: «((a d g) (b e h) (c f i) (m j) (n) (o) (p))␤»

say .join(",") for roundrobin([1, 2], [2, 3, 57, 77], [3, 4, 102]);
# OUTPUT: «1,2,3␤2,3,4␤57,102␤77␤»
Code

Therefore no data values are lost due in the 'zipping' operation. A record of which input list provided which element cannot be gleaned from the resulting sequence, however.

roundrobin can be useful in combining messy data to the point where a manual post-processing step can then be undertaken.

sub roundrobin(+list-of-lists, :$slip --> Seq)
Code

As of release 2022.02 of the Rakudo compiler, it is also possible to specify a :slip named argument. If specified with a true value, will slip the produced values.

say roundrobin <a b c>, <d e f m n o p>, <g h i j>, :slip;
# OUTPUT: «(a d g b e h c f i m j n o p)␤»
Code

routine sum§

sub    sum($list  )
method sum(List:D:)
Code

Returns the sum of all elements in the list or 0 if the list is empty. Throws an exception if an element can not be coerced into Numeric.

say (1, 3, pi).sum;       # OUTPUT: «7.14159265358979␤»
say (1, "0xff").sum;      # OUTPUT: «256␤»
say sum(0b1111, 5);       # OUTPUT: «20␤»
Code

If the list includes a Junction, the result will accordingly be a Junction:

say ( 1|2, 3).sum;            # OUTPUT: «any(4, 5)␤»
Code

When called on native integer arrays, it is also possible to specify a :wrap named parameter. This will add the values as native integers, wrapping around if they exceed the size of a native integer. If you are sure you will not exceed that value, or if you don't mind, using :wrap will make the calculation about 20x as fast.

my int @a = ^1_000_000;
say @a.sum(:wrap);        # OUTPUT: «499999500000␤»
Code

method fmt§

method fmt($format = '%s', $separator = ' ' --> Str:D)
Code

Returns a string where each element in the list has been formatted according to $format and where each element is separated by $separator. If the list contains nested sub-lists, then fmt will flatten them before formatting each element. Thus, fmt will treat [1, 2, [3, 4]] as a list with 4 elements rather than 3.

For more information about formats strings, see sprintf.

my @a = 8..11;
say @a.fmt('%03d', ',');  # OUTPUT: «008,009,010,011␤»
Code

method from§

Assumes the list contains Match objects and returns the value of .from called on the first element of the list.

'abcdefg' ~~ /(c)(d)/;
say $/.list.from;         # OUTPUT: «2␤»

"abc123def" ~~ m:g/\d/;
say $/.list.from;         # OUTPUT: «3␤»
Code

method to§

"abc123def" ~~ m:g/\d/;
say $/.to; # OUTPUT: «6␤»
Code

Assumes the List contains Matches, such as the $/ variable being a List, when using :g modifier in regexes. Returns the value of .to called on the last element of the list.

method sink§

method sink(--> Nil) { }
Code

It does nothing, and returns Nil, as the definition clearly shows.

sink [1,2,Failure.new("boo!"),"still here"]; # OUTPUT: «»
Code

method Set§

In general, creates a set which has as members elements of the list.

say <æ ß þ €>.Set;  # OUTPUT: «Set(ß æ þ €)␤»
Code

However, there might be some unexpected changes in case the list includes non-scalar data structures. For instance, with Pairs:

my @a = (:42a, :33b);
say @a;                # OUTPUT: «[a => 42 b => 33]␤»
say @a.Set;            # OUTPUT: «Set(a b)␤»
Code

The set will be composed of the keys of the Pair whose corresponding value is not 0, eliminating all the values. Please check the Set documentation for more examples and a more thorough explanation.

Operators§

infix cmp§

multi infix:<cmp>(List @a, List @b)
Code

Evaluates Lists by comparing element @a[$i] with @b[$i] (for some Int $i, beginning at 0) and returning Order::Less, Order::Same, or Order::More depending on if and how the values differ. If the operation evaluates to Order::Same, @a[$i + 1] is compared with @b[$i + 1]. This is repeated until one is greater than the other or all elements are exhausted.

If the Lists are of different lengths, at most only $n comparisons will be made (where $n = @a.elems min @b.elems). If all of those comparisons evaluate to Order::Same, the final value is selected based upon which List is longer.

say (1, 2, 3) cmp (1, 2, 3);   # OUTPUT: «Same␤»
say (4, 5, 6) cmp (4, 5, 7);   # OUTPUT: «Less␤»
say (7, 8, 9) cmp (7, 8, 8);   # OUTPUT: «More␤»

say (1, 2)    cmp (1, 2, 3);   # OUTPUT: «Less␤»
say (1, 2, 3) cmp (1, 2);      # OUTPUT: «More␤»
say (9).List  cmp (^10).List;  # OUTPUT: «More␤»
Code

Class relation diagram§

Rakudo Type Relation for List List List Cool Cool List->Cool is Positional Positional List->Positional does Iterable Iterable List->Iterable does