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'
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.
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
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)
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]]
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: