📘 Default values in Perl 6 subs

Perl 6 also allows specifying the default values of the sub’s arguments. Syntactically, this looks like an assignment.

sub i-live-in(Str $city = "Moscow") {  
    say "I live in $city.";            
}

i-live-in('Saint Petersburg');
i-live-in(); # The default city

It is also possible to pass values that are not known at the compile phase. When the default value is not a constant, it will be calculated at runtime.

sub to-pay($salary, $bonus = 100.rand) {
    return ($salary + $bonus).floor;
}

say to-pay(500, 50); # Always 550 net.
say to-pay(500);     # Any number between 500 and 600.
say to-pay(500);     # Same call but probably different output.

The “default” value will be calculated whenever it is required. Please also note that both rand and floor are called as methods, not as functions.

It is also possible to use previously passed parameters as default values:

sub f($a, $b = $a) {
    say $a + $b;
}

f(42);    # 84
f(42, -1) # 41

Optional parameters or parameters with default values must be listed after all the required ones because otherwise, the compiler will not be able to understand which is which.

📘 Subroutines, or subs in Perl 6

For a sub, which takes no arguments, its definition and the call are very straightforward and easy.

sub call-me {
    say "I'm called"
}

call-me;

The syntax for declaring a sub’s parameters is similar to what other languages (including Perl 5.20 and higher) provide.

sub cube($x) {
    return $x ** 3;
}

say cube(3); # 27

The required parameters are a comma-separated list in the parentheses immediately after the sub name. No other keywords, such as my, are required to declare them.

sub min($x, $y) {
    return $x < $y ?? $x !! $y;
}

say min(-2, 2);  # -2
say min(42, 24); # 24

(?? … !! is a ternary operator in Perl 6. Also, there’s a built-in operator min; see the details in the Chapter 2.)

The above-declared arguments are required; thus, if a sub is called with a different number of actual arguments, an error will occur.

📘 Anonymous code blocks in Perl 6

Perl 6 introduces the concept of so-called pointy blocks (or pointy arrow blocks). These are anonymous closure blocks, which return a reference to the function and can take arguments.

The syntax of defining pointy blocks is an arrow -> followed by the argument list and a block of code.

my $cube = -> $x {$x ** 3};
say $cube(3); # 27

Here, the block {$x ** 3}, which takes one argument $x, is created first. Then, it is called using a variable $cube as a reference to the function: $cube(3).

Pointy blocks are quite handy in loops.

for 1..10 -> $c {
    say $c;
}

The for loop takes two arguments: the range 1..10 and the block of code with the argument $c. The whole construction looks like syntactic sugar for loops.

There can be more than one argument. In that case, list them all after an arrow.

my $pow = -> $x, $p {$x ** $p};
say $pow(2, 15); # 32768

The same works with loops and with other Perl elements where you need passing anonymous code blocks.

for 0..9 -> $i, $j {
    say $i + $j;
}

In a loop iteration, two values from the list are consumed each time. So, the loop iterates five times and prints the sum of the pairs of numbers: 1, 5, 9, 13 and 17.

📘 Non-value argument passing in Perl 6 subs

By default, you pass the arguments by their values. Despite that, it is not possible to modify them inside the sub. To pass a variable by reference, add the is rw trait. (Note that formally this is not a reference but a mutable argument.)

sub inc($x is rw) {
    $x++;
}

my $value = 42;
inc($value);
say $value; # 43

📘 Anonymous subs in Perl 6

Let’s look at the creation of anonymous subs. One of the options (there are more than one) is to use syntax similar to what you often see in JavaScript.

say sub ($x, $y) {$x ~ ' ' ~ $y}("Perl", 6);

The first pair of parentheses contains the list of formal arguments of the anonymous sub; the second, the list of the arguments passed. The body of the sub is located between the braces. (The tilde denotes a string concatenation operator in Perl 6.)

By the way, it is important that there be no spaces before parentheses with the actual values of the sub parameters.

Another way of creating an anonymous sub is to use the arrow operator (->). We will discuss it later in the section dedicated to anonymous blocks.

📘 Modules in Perl 6

Basically, the Perl 6 modules are the files on disk containing the Perl 6 code. Modules are kept in files with the .pm extension. The disk hierarchy reflects the namespace enclosure, which means that a module named X::Y corresponds to the file X/Y.pm, which will be searched for in one of the predefined catalogues or in the location specified by the -I command line option. Perl 6 has more sophisticated rules for where and how to search for the real files (e. g., it can distinguish between different versions of the same module), but let us skip that for now.