Raku by Example: Lists and Arrays

A list is a collection of items separated by commas. Although parenthesis aren't necessary to create non-empty lists, empty lists are created with parenthesis.

> 1, 2;
(1 2)
> 'a', 'b';
(a b)
> 'adrian', 18, 'julie', 22;
(adrian 18 julie 22)
> my $evens = 2, 4, 8;
(2 4 8)
> my $empty-list = ();
()

Many operations can be performed on lists. For a complete catalog of methods applicable to lists, go to https://docs.perl6.org/type/List#Methods.

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

say $list[0];     # accessing item at index 0
say $list.elems;  # gets number of items in the list
say $list.head;   # returns the head of a list
say $list.tail;   # returns the tail of a list
say $list.end;    # returns the last item's index
$ perl6 lists.p6
1
3
1
b
2

A list is an immutable data structure. Thus operations attempting to modify the list itself will fail. However the elements themselves can be mutable and thus can be modified.

# This a list with immutable elements thus attempts to modify them will fail.
# Attempts to modify the list itself such as adding or removing elements will
# also fail.

my $reg-list = 'a', 2, 3;

$reg-list[0] = 1;   # Error: Cannot modify an immutable Str (a)
$reg-list.push(4);  # Error: Cannot resolve caller push...
$reg-list.pop;      # Error: No such method 'pop' for invocant of type 'Str'



# The following is a list with variables for elements. These variables are
# mutable so the list's items can be modified. However, attempting to mutate
# the list itself will fail.

my $v1 = 'a';
my $v2 = 2;
my $v3 = 3;

my $m-list = ($v1, $v2, $v3);

$m-list[0] = 'A';  # Works!
$m-list[1] = 'B';  # Works!
$m-list[3] = 'C';  # Works!
$m-list.push('D'); # Error: Cannot call 'push' on an immutable 'List'
$m-list.pop;       # Error: Cannot call 'pop' on an immutable 'List'

Array

Unlike a list, an array is a mutable data structure. Upon initialization/assignment its elements are containerized and thus can be modified. An array is usually declared by assigning list to an array variable (i.e., with the @ sigil). Alternatively, the array constructor [...] can be used.

> (1, 2, 3).^name
List
> my $list = (1, 2, 3); 
(1 2 3)
> $list.^name;
List
> [1, 2, 3].^name
Array
> my $array = (1, 2, 3);
[1 2 3]
> $array.^name;
Array
> my @array = (1, 2, 3);
[1 2 3]
> @array.^name;
Array

In addition to the methods/subroutines applicable to the List class, from which the Array class inherits, many other operations can be performed on arrays which include operations that modify the array itself.

my @beasts = 'shukaku', 'matatabi', 'isobu', 'son gokū', 'Kokuō',
             'saiken', 'chōmei', 'gyūki', 'kurama'; 

@beasts.elems;
@beasts.head;
say @beasts.pop;            # removes last item and returns it
say @beasts.shift;          # removes first item and returns it
@beasts.push('kurama');     # adds one or more elements to the end 
@beasts.unshift('shukaku'); # adds one or more elements to the start
say @beasts.splice(0, 7);   # removes n items starting from some index,
                            # returns them and replaces them with 
                            # replacement if provided

say "Remaining beasts: @beasts.join(' and ')";
$ perl6 array.p6
kurama
shukaku
[shukaku matatabi isobu son gokū Kokuō saiken chōmei]
Remaining beasts: gyūki and kurama

For a complete lists of methods/subs, go to https://docs.perl6.org/type/Array#Methods.

Typed arrays

To type an array, place the type between the declarator and the array's name.

my Int @only-ints = 1, 2, 3;
my Str @only-str  = 'A', 'a';

@only-ints.push(2.3);    # Error: Type check failed in assignment
@only-str.unshift(True); # Error: Type check failed in assignment

Fixed-size arrays

A fixed-size array is declared with a fix size and thus cannot be accessed beyond the defined size. To declare it, specify its maximum number of elements in square brackets immediately after its name.

my @b[2];
@b[0] = True;
@b[1] = False;

# A third element cannot neither be added
@b[2] = 'TF'; # Error: Index 2 for dimension 1 out of range (must be 0..1)

# nor accessed:
@b[2];        # Error: Index 2 for dimension 1 out of range (must be 0..1)

Multidimensional arrays

A multidimensional array is declared by specifying its semicolon-separated dimensions in square brackets immediately after its name.

my @students[3;2]; # Three rows with student's name and id for columns

@students[0;0] = 'David Smilyface';
@students[0;1] = '12345DS';
@students[1;0] = 'Karen Dolcia';
@students[1;1] = '12367KD';
@students[2;0] = 'Caty Green';
@students[2;1] = '23678CG';

say @students;
$ perl6 multi-arrays.p6
[[David Smilyface 12345DS] [Karen Dolcia 12367KD] [Caty Green 23678CG]]

List comprehensions

Raku has single-dimensional list comprehensions which can be achieved by using statements modifiers (if, unless, etc). Multidimensional comprehensions are also supported via the cross operator X when no dependency between the lists is needed. They usually have the following form: (expression st. modifier for list).

my @numbers = 1, 2, 3, 5, 6, 7, 8, 9, 10;

# All numbers from @number squared.
say ($_ ** 2 for @numbers);

# All numbers from @numbers whose product by 2 is greater
# than 15.
say ($_ if $_ * 2 >= 15 for @numbers);

# All numbers from 50 to 100 whose remainder when  divided
# with the number 7 is 3.
say ($_ if $_ mod 7 == 3 for (50..100));

# Using the cross operator to find all the possible
# products that are more than 50 using the lists (2, 5, 10)
# and (8, 10, 11).

say ( $_[0] * $_[1] if $_[0] * $_[1] > 50 for (2, 5, 10) X (8, 10, 11));
$ perl6 list-comp.p6
(1 4 9 25 36 49 64 81 100)
(8 9 10)
(52 59 66 73 80 87 94)
(55 80 100 110)

Although Raku 6 doesn't yet support multi-dimensional list comprehensions with dependencies between the lists, it can be achieved by using the gather..take construct.

my $n = 20;

# Finding Pythagorean triplets.
my @pyth = gather for 1..$n -> $x {
    for $x..$n -> $y {
        for $y..$n -> $z {
            take $x,$y,$z if $x**2+ $y**2 == $z**2;
         }
    }
}

say @pyth;
$ perl6 list-comp-dep.p6
[(3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20)]

For additional info, go to:

Back to main