Chars 7
Welcome to the official documentation of the Perl 6 programming language! Besides online browsing and searching, you can also view everything in one file or contribute by reporting mistakes or sending patches.
Language Reference & Tutorials
A collection of documents describing, in detail, the various conceptual parts of the language.
Type Reference
Index of built-in classes and roles.
Routine Reference
Index of built-in subroutines and methods.
Perl 6 Programs
A collection of documents describing how to run the Perl 6 executable program and other utilities, how to debug Perl 6 programs, and how to hack on Perl 6 source code.

The Perl 6 homepage offers a comprehensive list of Perl 6 resources, including tutorials, how-tos and FAQs (Frequently Asked Questions).

Perl 6 compiler developers may also be interested in The Perl 6 Specification. Documentation for the different but related Perl 5 language can be found on the Perl 5 documentation website.

1 Perl 6 by example P6-101

A basic introductory example of a Perl 6 program

Suppose that you host a table tennis tournament. The referees tell you the results of each game in the format Player1 Player2 | 3:2, which means that Player1 won against Player2 by 3 to 2 sets. You need a script that sums up how many matches and sets each player has won to determine the overall winner.

The input data (stored in a file called scores.txt) looks like this:

    Beth Ana Charlie Dave 
     Ana Dave | 3:0 
     Charlie Beth | 3:1 
     Ana Beth | 2:3 
     Dave Charlie | 3:0 
     Ana Charlie | 3:1 
     Beth Dave | 0:3 

The first line is the list of players. Every subsequent line records a result of a match.

Here's one way to solve that problem in Perl 6:

    use v6; 
 
     my $file  = open 'scores.txt'; 
     my @names = $file.get.words; 
 
     my %matches; 
     my %sets; 
 
     for $file.lines -> $line { 
         my ($pairing, $result) = $line.split(' | '); 
         my ($p1, $p2)          = $pairing.words; 
         my ($r1, $r2)          = $result.split(':'); 
 
         %sets{$p1} += $r1; 
         %sets{$p2} += $r2; 
 
         if $r1 > $r2 { 
             %matches{$p1}++; 
         } else { 
             %matches{$p2}++; 
         } 
     } 
 
     my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 
 
     for @sorted -> $n { 
         say "$n has won %matches{$n} matches and %sets{$n} sets"; 
     } 

This produces the output:

Ana has won 2 matches and 8 sets 
 Dave has won 2 matches and 6 sets 
 Charlie has won 1 matches and 4 sets 
 Beth has won 1 matches and 4 sets 

v6

Every Perl 6 program should begin with use v6;. This line tells the compiler which version of Perl the program expects. Should you accidentally run the file with Perl 5, you'll get a helpful error message.

statement

A Perl 6 program consists of zero or more statements. A statement ends with a semicolon or a curly bracket at the end of a line:

    my $file = open 'scores.txt'; 

lexical and block

my declares a lexical variable, which are visible only in the current block from the point of declaration to the end of the block. If there's no enclosing block, it's visible throughout the remainder of the file (which would effectively be the enclosing block). A block is any part of the code enclosed between curly braces { }.

sigil and identifier

A variable name begins with a sigil, which is a non-alpha-numeric symbol such as $, @, %, or &--or occasionally the double colon ::. Sigils indicate the structural interface for the variable, such as whether it should be treated as a single value, a compound value, a subroutine, etc. After the sigil comes an identifier, which may consist of letters, digits and the underscore. Between letters you can also use a dash - or an apostrophe ', so isn't and double-click are valid identifiers.

scalar

Sigils indicate the default access method for a variable. Variables with the @ sigil are accessed positionally; variables with the % sigil are accessed by string key. The $ sigil, however, indicates a general scalar container that can hold any single value and be accessed in any manner. A scalar can even contain a compound object like an Array or a Hash; the $ sigil signifies that it should be treated as a single value, even in a context that expects multiple values (as with an Array or Hash).

filehandle and assignment

The built-in function open opens a file, here named scores, and returns a filehandle--an object representing that file. The equality sign = assigns that filehandle to the variable on the left, which means that $file now stores the filehandle.

string literal

'scores.txt' is a string literal. A string is a piece of text, and a string literal is a string which appears directly in the program. In this line, it's the argument provided to open.

    my @names = $file.get.words; 

array, method and invocant

The right-hand side calls a method --a named group of behavior-- named get on the filehandle stored in $file. The get method reads and returns one line from the file, removing the line ending. If you print the contents of $file after calling get, you will see that the first line is no longer in there. words is also a method, called on the string returned from get. words decomposes its invocant--the string on which it operates--into a list of words, which here means strings separated by whitespace. It turns the single string 'Beth Ana Charlie Dave' into the list of strings 'Beth', 'Ana', 'Charlie', 'Dave'.

Finally, this list gets stored in the Array @names. The @ sigil marks the declared variable as an Array. Arrays store ordered lists.

    my %matches; 
     my %sets; 

hash

These two lines of code declare two hashes. The % sigil marks each variable as a Hash. A Hash is an unordered collection of key-value pairs. Other programming languages call that a hash table, dictionary, or map. You can query a hash table for the value that corresponds to a certain $key with %hash{$key}

Unlike Perl 5, in Perl 6 the sigil does not change when accessing an array or hash with [ ] or { } . This is called sigil invariance
.

In the score counting program, %matches stores the number of matches each player has won. %sets stores the number of sets each player has won. Both of these hashes are indexed by the player's name.

    for $file.lines -> $line { 
         ... 
     } 

for and block

for produces a loop that runs the block delimited by curly brackets once for each item of the list, setting the variable $line to the current value of each iteration. $file.lines produces a list of the lines read from the file scores.txt, starting with the second line of the file since we already called $file.get once, and going all the way to the end of the file.

During the first iteration, $line will contain the string Ana Dave | 3:0; during the second, Charlie Beth | 3:1, and so on.

    my ($pairing, $result) = $line.split(' | '); 

my can declare multiple variables simultaneously. The right-hand side of the assignment is a call to a method named split, passing along the string ' | ' as an argument.

split decomposes its invocant into a list of strings, so that joining the list items with the separator ' | ' produces the original string.

$pairing gets the first item of the returned list, and $result the second.

After processing the first line, $pairing will hold the string Ana Dave and $result 3:0.

The next two lines follow the same pattern:

    my ($p1, $p2) = $pairing.words; 
     my ($r1, $r2) = $result.split(':'); 

The first extracts and stores the names of the two players in the variables $p1 and $p2. The second extracts the results for each player and stores them in $r1 and $r2.

After processing the first line of the file, the variables contain the values: cell '0'

Variable Contents
$line 'Ana Dave | 3:0'
$pairing 'Ana Dave'
$result '3:0'
$p1 'Ana'
$p2 'Dave'
$r1 '3'
$r2 '0'

The program then counts the number of sets each player has won:

    %sets{$p1} += $r1; 
     %sets{$p2} += $r2; 

The += assignment operator is a shortcut for:

    %sets{$p1} = %sets{$p1} + $r1; 
     %sets{$p2} = %sets{$p2} + $r2; 

Any and +=

+= $r1 means increase the value in the variable on the left by $r1. In the first iteration %sets{$p1} is not yet set, so it defaults to a special value called Any. The addition and incrementing operators treat Any as a number with the value of zero; the strings get automatically converted to numbers, as addition is a numeric operation.

fat arrow, pair and autovivification

Before these two lines execute, %sets is empty. Adding to an entry that is not in the hash yet will cause that entry to spring into existence just-in-time, with a value starting at zero. (This is autovivification). After these two lines have run for the first time, %sets contains 'Ana' => 3, 'Dave' => 0 . (The fat arrow => separates key and value in a Pair.)

    if $r1 > $r2 { 
         %matches{$p1}++; 
     } else { 
         %matches{$p2}++; 
     } 

If $r1 is numerically larger than $r2, %matches{$p1} increments by one. If $r1 is not larger than $r2, %matches{$p2} increments. Just as in the case of +=, if either hash value did not exist previously, it is autovivified by the increment operation.

postincrement and preincrement

$thing++ is short for $thing += 1 or $thing = $thing + 1, with the small exception that the return value of the expression is $thing before the increment, not the incremented value. As in many other programming languages, you can use ++ as a prefix. Then it returns the incremented value; my $x = 1; say ++$x prints 2.

my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

variables, $_

This line consists of three individually simple steps. An array's sort method returns a sorted version of the array's contents. However, the default sort on an array sorts by its contents. To print player names in winner-first order, the code must sort the array by the scores of the players, not their names. The sort method's argument is a block used to transform the array elements (the names of players) to the data by which to sort. The array items are passed in through the topic variable $_.

block

You have seen blocks before: both the for loop -> $line { ... } and the if statement worked on blocks. A block is a self-contained piece of Perl 6 code with an optional signature (the -> $line part).

The simplest way to sort the players by score would be @names.sort({ %matches{$_} }), which sorts by number of matches won. However Ana and Dave have both won two matches. That simple sort doesn't account for the number of sets won, which is the secondary criterion to decide who has won the tournament.

stable sort

When two array items have the same value, sort leaves them in the same order as it found them. Computer scientists call this a stable sort. The program takes advantage of this property of Perl 6's sort to achieve the goal by sorting twice: first by the number of sets won (the secondary criterion), then by the number of matches won.

After the first sorting step, the names are in the order Beth Charlie Dave Ana. After the second sorting step, it's still the same, because no one has won fewer matches but more sets than someone else. Such a situation is entirely possible, especially at larger tournaments.

sort sorts in ascending order, from smallest to largest. This is the opposite of the desired order. Therefore, the code calls the .reverse method on the result of the second sort, and stores the final list in @sorted.

    for @sorted -> $n { 
         say "$n has won %matches{$n} matches and %sets{$n} sets"; 
     } 

say, print and put

To print out the players and their scores, the code loops over @sorted, setting $n to the name of each player in turn. Read this code as "For each element of sorted, set $n to the element, then execute the contents of the following block." say prints its arguments to the standard output (the screen, normally), followed by a newline. (Use print if you don't want the newline at the end.)

Note that say will truncate certain data structures by calling the .gist method so put is safer if you want exact output.

interpolation

When you run the program, you'll see that say doesn't print the contents of that string verbatim. In place of $n it prints the contents of the variable $n-- the names of players stored in $n. This automatic substitution of code with its contents is interpolation. This interpolation happens only in strings delimited by double quotes "...". Single quoted strings '...' do not interpolate:

double-quoted strings and single-quoted strings

    my $names = 'things'; 
     say 'Do not call me $names'; # OUTPUT: «Do not call me $names␤» 
     say "Do not call me $names"; # OUTPUT: «Do not call me things␤» 

Double quoted strings in Perl 6 can interpolate variables with the $ sigil as well as blocks of code in curly braces. Since any arbitrary Perl code can appear within curly braces, Arrays and Hashes may be interpolated by placing them within curly braces.

Arrays within curly braces are interpolated with a single space character between each item. Hashes within curly braces are interpolated as a series of lines. Each line will contain a key, followed by a tab character, then the value associated with that key, and finally a newline.

Let's see an example of this now.

In this example, you will see some special syntax that makes it easier to make a list of strings. This is the <...> quote-words construct. When you put words in between the < and > they are all assumed to be strings, so you do not need to wrap them each in double quotes "..." .

    say "Math: { 1 + 2 }";                  # OUTPUT: «Math: 3␤» 
     my @people = <Luke Matthew Mark>; 
     say "The synoptics are: {@people}";     # OUTPUT: «The synoptics are: Luke Matthew Mark␤» 
 
     say "{%sets}␤";                         # From the table tennis tournament 
 
     # Charlie 4 
     # Dave    6 
     # Ana     8 
     # Beth    4 

When array and hash variables appear directly in a double-quoted string (and not inside curly brackets), they are only interpolated if their name is followed by a postcircumfix -- a bracketing pair that follows a statement. It's also ok to have a method call between the variable name and the postcircumfix.

Zen slice

    my @flavours = <vanilla peach>; 
 
     say "we have @flavours";           # OUTPUT: «we have @flavours␤» 
     say "we have @flavours[0]";        # OUTPUT: «we have vanilla␤» 
     # so-called "Zen slice" 
     say "we have @flavours[]";         # OUTPUT: «we have vanilla peach␤» 
 
     # method calls ending in postcircumfix 
     say "we have @flavours.sort()";    # OUTPUT: «we have peach vanilla␤» 
 
     # chained method calls: 
     say "we have @flavours.sort.join(', ')"; 
                                     # OUTPUT: «we have peach, vanilla␤» 

Exercises

1. The input format of the example program is redundant: the first line containing the name of all players is not necessary, because you can find out which players participated in the tournament by looking at their names in the subsequent rows.

How can you make the program run if you do not use the @names variable? Hint: %hash.keys returns a list of all keys stored in %hash.

Answer: Remove the line my @names = $file.get.words;, and change:

    my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

... into:

    my @sorted = %sets.keys.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

2. Instead of deleting the redundant @names variable, you can also use it to warn if a player appears that wasn't mentioned in the first line, for example due to a typo. How would you modify your program to achieve that?

Hint: Try using membership operators.

Answer: Change @names to @valid-players. When looping through the lines of the file, check to see that $p1 and $p2 are in @valid-players. Note that for membership operators you can also use (elem) and !(elem).

    ...; 
     my @valid-players = $file.get.words; 
     ...; 
 
     for $file.lines -> $line { 
         my ($pairing, $result) = $line.split(' | '); 
         my ($p1, $p2)          = $pairing.split(' '); 
         if $p1 ∉ @valid-players { 
             say "Warning: '$p1' is not on our list!"; 
         } 
         if $p2 ∉ @valid-players { 
             say "Warning: '$p2' is not on our list!"; 
         } 
         ... 
     } 

2 Perl 5 to Perl 6 guide - In a Nutshell

How do I do what I used to do? (Perl 6 in a nutshell)

This page attempts to provide a fast-path to the changes in syntax and semantics from Perl 5 to Perl 6. Whatever worked in Perl 5 and must be written differently in Perl 6, should be listed here (whereas many new Perl 6 features and idioms are not).

Hence this should not be mistaken for a beginner tutorial or a promotional overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Perl 5 background and for anyone porting Perl 5 code to Perl 6 (though note that #Automated Translation might be more convenient).

A note on semantics; when we say "now" in this document, we mostly just mean "now that you are trying out Perl 6." We don't mean to imply that Perl 5 is now suddenly obsolete. Quite the contrary, most of us love Perl 5, and we expect Perl 5 to continue in use for a good many years. Indeed, one of our more important goals has been to make interaction between Perl 5 and Perl 6 run smoothly. However, we do also like the design decisions in Perl 6, which are certainly newer and arguably better integrated than many of the historical design decisions in Perl 5. So many of us do hope that over the next decade or two, Perl 6 will become the more dominant language. If you want to take "now" in that future sense, that's okay too. But we're not at all interested in the either/or thinking that leads to fights.

CPAN

See https://modules.perl6.org/ .

If the module that you were using has not been converted to Perl 6, and no alternative is listed in this document, then its use under Perl 6 may not have been addressed yet.

The Inline::Perl5 project makes it possible to use Perl 5 modules directly from Perl 6 code by using an embedded instance of the perl interpreter to run Perl 5 code.

This is as simple as:

# the :from<Perl5> makes Perl 6 load Inline::Perl5 first (if installed) 
 # and then load the Scalar::Util module from Perl 5 
 use Scalar::Util:from<Perl5> <looks_like_number>; 
 say looks_like_number "foo";   # 0 
 say looks_like_number "42";    # 1 

A number of Perl 5 modules have been ported to Perl 6, trying to maintain the API of these modules as much as possible, as part of the CPAN Butterfly Plan. These can be found at https://modules.perl6.org/t/CPAN5.

Many Perl 5 built-in functions (about a 100 so far) have been ported to Perl 6 with the same semantics. Think about the shift function in Perl 5 having magic shifting from @_ or @ARGV by default, depending on context. These can be found at https://modules.perl6.org/t/Perl5 as separately loadable modules, and in the P5built-ins bundle to get them all at once.

Syntax

Identifiers

In identifiers, Perl 6 allows the use of dashes (-), underscores (_), apostrophes ('), and alphanumerics:

sub test-doesn't-hang { ... }
my $ความสงบ = 42;
my \Δ = 72; say 72 - Δ;

-> Method calls

If you've read any Perl 6 code at all, it's immediately obvious that method call syntax now uses a dot instead of an arrow:

$person->name  # Perl 5 
$person.name   # Perl 6 

The dot notation is both easier to type and more of an industry standard. But we also wanted to steal the arrow for something else. (Concatenation is now done with the ~ operator, if you were wondering.)

To call a method whose name is not known until runtime:

$object->$methodname(@args);  # Perl 5 
$object."$methodname"(@args); # Perl 6 

If you leave out the quotes, then Perl 6 expects $methodname to contain a Method object, rather than the simple string name of the method. Yes, everything in Perl 6 can be considered an object.

Whitespace

Perl 5 allows a surprising amount of flexibility in the use of whitespace, even with strict mode and warnings turned on:

# unidiomatic but valid Perl 5 
 say"Hello ".ucfirst  ($people 
     [$ i] 
     -> 
     name)."!"if$greeted[$i]<1; 

Perl 6 also endorses programmer freedom and creativity, but balanced syntactic flexibility against its design goal of having a consistent, deterministic, extensible grammar that supports single-pass parsing and helpful error messages, integrates features like custom operators cleanly, and doesn't lead programmers to accidentally misstate their intent. Also, the practice of "code golf" is slightly de-emphasized; Perl 6 is designed to be more concise in concepts than in keystrokes.

As a result, there are various places in the syntax where whitespace is optional in Perl 5, but is either mandatory or forbidden in Perl 6. Many of those restrictions are unlikely to concern much real-life Perl code (e.g., whitespace being disallowed between the sigil and name of a variable), but there are a few that will unfortunately conflict with some Perl hackers' habitual coding styles:

However, note that you can use unspace to add whitespace in Perl 6 code in places where it is otherwise not allowed.

See also S03#Minimal whitespace DWIMmery and S04#Statement parsing in the Perl 6 design docs.

Sigils

In Perl 5, arrays and hashes use changing sigils depending on how they are being accessed. In Perl 6 the sigils are invariant, no matter how the variable is being used - you can think of them as part of the variable's name.

$ Scalar

The $ sigil is now always used with "scalar" variables (e.g. $name), and no longer for array indexing and Hash indexing. That is, you can still use $x[1] and $x{"foo"}, but it will act on $x, with no effect on a similarly named @x or %x. Those would now be accessed with @x[1] and %x{"foo"}.

@ Array

The @ sigil is now always used with "array" variables (e.g. @months, @months[2], @months[2, 4]), and no longer for value-slicing hashes.

% Hash

The % sigil is now always used with "hash" variables (e.g. %calories, %calories<apple>, %calories<pear plum>), and no longer for key/value-slicing arrays.

& Sub

The & sigil is now used consistently (and without the help of a backslash) to refer to the function object of a named subroutine/operator without invoking it, i.e. to use the name as a "noun" instead of a "verb":

my $sub = \&foo; # Perl 5 
my $sub = &foo;  # Perl 6 
callback => sub { say @_ }  # Perl 5 - can't pass built-in sub directly 
callback => &say            # Perl 6 - & gives "noun" form of any sub 

Since Perl 6 does not allow adding/removing symbols in a lexical scope once it has finished compiling, there is no equivalent to Perl 5's undef &foo;, and the closest equivalent to Perl 5's defined &foo would be defined ::('&foo') (which uses the "dynamic symbol lookup" syntax). However, you can declare a mutable named subroutine with my &foo; and then change its meaning at runtime by assigning to &foo.

In Perl 5, the ampersand sigil can additionally be used to call subroutines in special ways with subtly different behavior compared to normal sub calls. In Perl 6 those special forms are no longer available:

* Glob

TODO: Research what exact use-cases still need typeglobs in Perl 5 today, and refactor this section to list them (with translations).

In Perl 5, the * sigil referred to the GLOB structure that Perl uses to store non-lexical variables, filehandles, subs, and formats.

(This should not be confused with the Perl 5 built-in glob() function, which reads filenames from a directory).

You are most likely to encounter a GLOB in code written on a early Perl version that does not support lexical filehandles, when a filehandle needed to be passed into a sub.

# Perl 5 - ancient method 
 sub read_2 { 
     local (*H) = @_; 
     return scalar(<H>), scalar(<H>); 
 } 
 open FILE, '<', $path or die; 
 my ($line1, $line2) = read_2(*FILE); 

You should refactor your Perl 5 code to remove the need for the GLOB, before translating into Perl 6.

# Perl 5 - modern use of lexical filehandles 
 sub read_2 { 
     my ($fh) = @_; 
     return scalar(<$fh>), scalar(<$fh>); 
 } 
 open my $in_file, '<', $path or die; 
 my ($line1, $line2) = read_2($in_file); 

And here's just one possible Perl 6 translation:

# Perl 6 
 sub read-n($fh, $n) { 
     return $fh.get xx $n; 
 } 
 my $in-file = open $path or die; 
 my ($line1, $line2) = read-n($in-file, 2); 

[] Array indexing/slicing

Index and slice operations on arrays no longer inflect the variable's sigil, and adverbs can be used to control the type of slice:

Also note that the subscripting brackets are now a normal postcircumfix operator rather than a special syntactic form, and thus checking for existence of elements and unsetting elements is done with adverbs.

{} Hash indexing/slicing

Index and slice operations on hashes no longer inflect the variable's sigil, and adverbs can be used to control the type of slice. Also, single-word subscripts are no longer magically autoquoted inside the curly braces; instead, the new angle-brackets version is available which always autoquotes its contents (using the same rules as the qw// quoting construct):

Also note that the subscripting curly braces are now a normal postcircumfix operator rather than a special syntactic form, and thus checking for existence of keys and removing keys is done with adverbs.

Creating references and using them

In Perl 5, references to anonymous arrays and hashes and subs are returned during their creation. References to existing named variables and subs were generated with the \ operator. the "referencing/dereferencing" metaphor does not map cleanly to the actual Perl 6 container system, so we will have to focus on the intent of the reference operators instead of the actual syntax.

my $aref = \@aaa  ; # Perl 5 

This might be used for passing a reference to a routine, for instance. But in Perl 6, the (single) underlying object is passed (which you could consider to be a sort of pass by reference).

my @array = 4,8,15; 
 { $_[0] = 66 }(@array);   # run the block with @array aliased to $_ 
 say @array; #  OUTPUT: «[66 8 15]␤» 

The underlying Array object of @array is passed, and its first value modified inside the declared routine.

In Perl 5, the syntax for dereferencing an entire reference is the type-sigil and curly braces, with the reference inside the curly braces. In Perl 6, this concept simply does not apply, since the reference metaphor does not really apply.

In Perl 5, the arrow operator, -> , is used for single access to a composite's reference or to call a sub through its reference. In Perl 6, the dot operator . is always used for object methods, but the rest does not really apply.

# Perl 5 
     say $arrayref->[7]; 
     say $hashref->{'fire bad'}; 
     say $subref->($foo, $bar); 

In relatively recent versions of Perl 5 (5.20 and later), a new feature allows the use of the arrow operator for dereferencing: see Postfix Dereferencing. This can be used to create an array from a scalar. This operation is usually called decont, as in decontainerization, and in Perl 6 methods such as .list and .hash are used:

# Perl 5.20 
     use experimental qw< postderef >; 
     my @a = $arrayref->@*; 
     my %h = $hashref->%*; 
     my @slice = $arrayref->@[3..7]; 
# Perl 6 
     my @a = $contains-an-array.list;        # or @($arrayref) 
     my %h = $contains-a-hash.hash;          # or %($hashref) 

The "Zen" slice does the same thing:

# Perl 6 
     my @a = $contains-an-array[]; 
     my %h = $contains-a-hash{}; 

See the "Containers" section of the documentation for more information.

Operators

See S03/Operators for full details on all operators.

Unchanged:

, (Comma) List Separator

Unchanged, but note that in order to flatten an array variable to a list (in order to append or prefix more items) one should use the | operator (see also Slip). For instance:

my @numbers = 100, 200, 300; 
 my @more_numbers = 500, 600, 700; 
 my @all_numbers = |@numbers, 400, |@more_numbers; 

That way one can concatenate arrays.

Note that one does not need to have any parentheses on the right-hand side: the List Separator takes care of creating the list, not the parentheses!

<=> cmp Three-way comparisons

In Perl 5, these operators returned -1, 0, or 1. In Perl 6, they return Order::Less, Order::Same, or Order::More.

cmp is now named leg; it forces string context for the comparison.

<=> still forces numeric context.

cmp in Perl 6 does either <=> or leg, depending on the existing type of its arguments.

~~ Smartmatch operator

While the operator has not changed, the rules for what exactly is matched depend on the types of both arguments, and those rules are far from identical in Perl 5 and Perl 6. See ~~ and S03/Smartmatching

& | ^ String Bitwise ops

& | ^ Numeric Bitwise ops

& | ^ Boolean ops

In Perl 5, & | ^ were invoked according to the contents of their arguments. For example, 31 | 33 returns a different result than "31" | "33".

In Perl 6, those single-character ops have been removed, and replaced by two-character ops which coerce their arguments to the needed context.

# Infix ops (two arguments; one on each side of the op) 
 +&  +|  +^  And Or Xor: Numeric 
 ~&  ~|  ~^  And Or Xor: String 
 ?&  ?|  ?^  And Or Xor: Boolean 
 
 # Prefix ops (one argument, after the op) 
 +^  Not: Numeric 
 ~^  Not: String 
 ?^  Not: Boolean (same as the ! op) 

<< >> Numeric shift left|right ops

Replaced by +< and +> .

say 42 << 3; # Perl 5 
say 42 +< 3; # Perl 6 

=> Fat comma

In Perl 5, => acted just like a comma, but also quoted its left-hand side.

In Perl 6, => is the Pair operator, which is quite different in principle, but works the same in many situations.

If you were using => in hash initialization, or in passing arguments to a sub that expects a hashref, then the usage is likely identical.

sub get_the_loot { ... }; # Perl 6 stub
# Works in Perl 5 and Perl 6
my %hash = ( AAA => 1, BBB => 2 );
get_the_loot( 'diamonds', { quiet_level => 'very', quantity => 9 }); # Note the curly braces

If you were using => as a convenient shortcut to not have to quote part of a list, or in passing arguments to a sub that expects a flat list of KEY, VALUE, KEY, VALUE, then continuing to use => may break your code. The easiest workaround is to change the fat comma to a regular comma, and manually add quotes to its left-hand side. Or, you can change the sub's API to slurp a hash. A better long-term solution is to change the sub's API to expect Pairs; however, this requires you to change all sub calls at once.

# Perl 5 
 sub get_the_loot { 
     my $loot = shift; 
     my %options = @_; 
     # ... 
 } 
 # Note: no curly braces in this sub call 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); 
# Perl 6, original API 
 sub get_the_loot( $loot, *%options ) { # The * means to slurp everything 
     ... 
 } 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); # Note: no curly braces in this API 
 
 # Perl 6, API changed to specify valid options 
 # The colon before the sigils means to expect a named variable, 
 # with the key having the same name as the variable. 
 sub get_the_loot( $loot, :$quiet_level?, :$quantity = 1 ) { 
     # This version will check for unexpected arguments! 
     ... 
 } 
 get_the_loot( 'diamonds', quietlevel => 'very' ); # Throws error for misspelled parameter name 

? : Ternary operator

The conditional operator ? : has been replaced by ?? !!:

my $result = $score > 60 ?  'Pass' :  'Fail'; # Perl 5 
my $result = $score > 60 ?? 'Pass' !! 'Fail'; # Perl 6 

. (Dot) String Concatenation

Replaced by the tilde.

Mnemonic: think of "stitching" together the two strings with needle and thread.

$food = 'grape' . 'fruit'; # Perl 5 
$food = 'grape' ~ 'fruit'; # Perl 6 

x List Repetition or String Repetition operator

In Perl 5, x is the Repetition operator, which behaves differently in scalar or list contexts:

Perl 6 uses two different Repetition operators to achieve the above:

Mnemonic: x is short and xx is long, so xx is the one used for lists.

# Perl 5 
     print '-' x 80;             # Print row of dashes 
     @ones = (1) x 80;           # A list of 80 1's 
     @ones = (5) x @ones;        # Set all elements to 5 
# Perl 6 
     print '-' x 80;             # Unchanged 
     @ones = 1 xx 80;            # Parentheses no longer needed 
     @ones = 5 xx @ones;         # Parentheses no longer needed 

.. ... Two Dots or Three Dots, Range op or Flipflop op

In Perl 5, .. was one of two completely different operators, depending on context.

In list context, .. is the familiar range operator. Ranges from Perl 5 code should not require translation.

In scalar context, .. and ... were the little-known Flipflop operators. They have been replaced by ff and fff.

String interpolation

In Perl 5, "${foo}s" deliminates a variable name from regular text next to it. In Perl 6, simply extend the curly braces to include the sigil too: "{$foo}s". This is in fact a very simple case of interpolating an expression.

Compound Statements

Conditionals

if elsif else unless

Mostly unchanged; parentheses around the conditions are now optional, but if used, must not immediately follow the keyword, or it will be taken as a function call instead. Binding the conditional expression to a variable is also a little different:

if (my $x = dostuff()) {...}  # Perl 5 
if dostuff() -> $x {...}      # Perl 6 

(You can still use the my form in Perl 6, but it will scope to the outer block, not the inner.)

The unless conditional only allows for a single block in Perl 6; it does not allow for an elsif or else clause.

given-when

The given-when construct is like a chain of if-elsif-else statements or like the switch-case construct in e.g. C. It has the general structure:

given EXPR { 
     when EXPR { ... } 
     when EXPR { ... } 
     default { ... } 
 } 

In its simplest form, the construct is as follows:

given $value {                   # assigns $_ 
     when "a match" {             # if $_ ~~ "a match" 
         # do-something(); 
     } 
     when "another match" {       # elsif $_ ~~ "another match" 
         # do-something-else(); 
     } 
     default {                    # else 
         # do-default-thing(); 
     } 
 } 

This is simple in the sense that a scalar value is matched in the when statements against $_, which was set by the given. More generally, the matches are actually smartmatches on $_ such that lookups using more complex entities such as regexps can be used instead of scalar values.

See also the warnings on the smartmatch op above.

Loops

while until

Mostly unchanged; parentheses around the conditions are now optional, but if used, must not immediately follow the keyword, or it will be taken as a function call instead. Binding the conditional expression to a variable is also a little different:

while (my $x = dostuff()) {...}  # Perl 5 
while dostuff() -> $x {...}      # Perl 6 

(You can still use the my form in Perl 6, but it will scope to the outer block, not the inner.)

Note that reading line-by-line from a filehandle has changed.

In Perl 5, it was done in a while loop using the diamond operator. Using for instead of while was a common bug, because the for causes the whole file to be sucked in at once, swamping the program's memory usage.

In Perl 6, for statement is lazy, so we read line-by-line in a for loop using the .lines method.

while (<IN_FH>)  { } # Perl 5 
for $IN_FH.lines { } # Perl 6 

Also note that in Perl 6, lines are chomped by default.

do while/until

# Perl 5 
 do { 
     ... 
 } while $x < 10; 
 
 do { 
     ... 
 } until $x >= 10; 

The construct is still present, but do was renamed to repeat, to better represent what the construct does:

# Perl 6 
 repeat { 
     ... 
 } while $x < 10; 
 
 repeat { 
     ... 
 } until $x >= 10; 

for foreach

Note first this common misunderstanding about the for and foreach keywords. Many programmers think that they distinguish between the C-style three-expression form and the list-iterator form; they do not! In fact, the keywords are interchangeable; the Perl 5 compiler looks for the semi-colons within the parentheses to determine which type of loop to parse.

The C-style three-factor form now uses the loop keyword, and is otherwise unchanged. The parentheses are still required.

for  ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 5 
loop ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 6 

The loop-iterator form is named for in Perl 6 and foreach is no longer a keyword. The for loop has the following rules:

for my $car (@cars)  {...} # Perl 5; read-write 
for @cars  -> $car   {...} # Perl 6; read-only 
 for @cars <-> $car   {...} # Perl 6; read-write 

If the default topic $_ is being used, it is also read-write.

for (@cars)      {...} # Perl 5; $_ is read-write 
for @cars        {...} # Perl 6; $_ is read-write 
 for @cars <-> $_ {...} # Perl 6; $_ is also read-write 

It is possible to consume more than one element of the list in each iteration simply specifying more than one variable after the arrow operator:

my @array = 1..10; 
 for @array -> $first, $second { 
     say "First is $first, second is $second"; 
 } 

each

Here is the equivalent to Perl 5’s while…each(%hash) or while…each(@array) (i.e., iterating over both the keys/indices and values of a data structure) in Perl 6:

while (my ($i, $v) = each(@array)) { ... } # Perl 5 
for @array.kv -> $i, $v { ... } # Perl 6 
while (my ($k, $v) = each(%hash)) { ... } # Perl 5 
for %hash.kv -> $k, $v { ... } # Perl 6 

Flow Control statements

Unchanged:

continue

There is no longer a continue block. Instead, use a NEXT block (phaser) within the body of the loop.

# Perl 5 
     my $str = ''; 
     for (1..5) { 
         next if $_ % 2 == 1; 
         $str .= $_; 
     } 
     continue { 
         $str .= ':' 
     } 
# Perl 6 
     my $str = ''; 
     for 1..5 { 
         next if $_ % 2 == 1; 
         $str ~= $_; 
         NEXT { 
             $str ~= ':' 
         } 
     } 

Please note that phasers don't really need a block. This can be very handy when you don't want another scope:

# Perl 6 
     my $str = ''; 
     for 1..5 { 
         next if $_ % 2 == 1; 
         $str ~= $_; 
         NEXT $str ~= ':'; 
     } 

Functions

NOTE FOR EDITORS: When adding functions, please place them in alphabetical order.

Built-ins with bare blocks

Builtins that previously accepted a bare block followed, without a comma, by the remainder of the arguments will now require a comma between the block and the arguments e.g. map, grep, etc.

my @results = grep { $_ eq "bars" } @foo; # Perl 5 
my @results = grep { $_ eq "bars" }, @foo; # Perl 6 

delete

Turned into an adverb of the {} hash subscripting and [] array subscripting operators.

my $deleted_value = delete $hash{$key};  # Perl 5 
my $deleted_value = %hash{$key}:delete;  # Perl 6 - use :delete adverb 
my $deleted_value = delete $array[$i];  # Perl 5 
my $deleted_value = @array[$i]:delete;  # Perl 6 - use :delete adverb 

exists

Turned into an adverb of the {} hash subscripting and [] array subscripting operators.

say "element exists" if exists $hash{$key};  # Perl 5 
say "element exists" if %hash{$key}:exists;  # Perl 6 - use :exists adverb 
say "element exists" if exists $array[$i];  # Perl 5 
say "element exists" if @array[$i]:exists;  # Perl 6 - use :exists adverb 

Regular Expressions ( Regex / Regexp )

Change =~ and !~ to ~~ and !~~ .

In Perl 5, matches and substitutions are done against a variable using the =~ regexp-binding op.

In Perl 6, the ~~ smartmatch op is used instead.

next if $line  =~ /static/  ; # Perl 5 
next if $line  ~~ /static/  ; # Perl 6 
next if $line  !~ /dynamic/ ; # Perl 5 
next if $line !~~ /dynamic/ ; # Perl 6 
$line =~ s/abc/123/;          # Perl 5 
$line ~~ s/abc/123/;          # Perl 6 

Alternately, the new .match and .subst methods can be used. Note that .subst is non-mutating. See S05/Substitution.

Captures start with 0, not 1

/(.+)/ and print $1; # Perl 5 
/(.+)/ and print $0; # Perl 6 

Move modifiers

Move any modifiers from the end of the regex to the beginning. This may require you to add the optional m on a plain match like /abc/.

next if $line =~    /static/i ; # Perl 5 
next if $line ~~ m:i/static/  ; # Perl 6 

Add :P5 or :Perl5 adverb

If the actual regex is complex, you may want to use it as-is, by adding the P5 modifier.

next if $line =~    m/[aeiou]/   ; # Perl 5 
next if $line ~~ m:P5/[aeiou]/   ; # Perl 6, using P5 modifier 
 next if $line ~~ m/  <[aeiou]> / ; # Perl 6, native new syntax 

Please note that the Perl 5 regular expression syntax dates from many years ago and may lack features that have been added since the beginning of the Perl 6 project.

Special matchers generally fall under the <> syntax

There are many cases of special matching syntax that Perl 5 regexes support. They won't all be listed here, but often instead of being surrounded by (), the assertions will be surrounded by <>.

For character classes, this means that:

For lookaround assertions:

For more info see lookahead assertions.

(Unrelated to <> syntax, the "lookaround" /foo\Kbar/ becomes /foo <( bar )> /

Longest token matching (LTM) displaces alternation

In Perl 6 regexes, | does LTM, which decides which alternation wins an ambiguous match based off of a set of rules, rather than about which was written first.

The simplest way to deal with this is just to change any | in your Perl 5 regex to a ||.

However, if a regex written with || is inherited or composed into a grammar that uses | either by design or typo, the result may not work as expected. So when the matching process becomes complex, you finally need to have some understanding of both, especially how LTM strategy works. Besides, | may be a better choice for grammar reuse.

TODO more rules. Use translate_regex.pl from Blue Tiger in the meantime.

Comments

As with Perl 5, comments work as usual in regexes.

/ word #`(match lexical "word") /

Pragmas

strict

Strict mode is now on by default.

warnings

Warnings are now on by default.

no warnings is currently NYI, but putting things in a quietly {} block will silence.

autodie

The functions which were altered by autodie to throw exceptions on error, now generally return Failures by default. You can test a Failure for definedness / truthiness without any problem. If you use the Failure in any other way, then the Exception that was encapsulated by the Failure will be thrown.

# Perl 5 
 open my $i_fh, '<', $input_path;  # Fails silently on error 
 use autodie; 
 open my $o_fh, '>', $output_path; # Throws exception on error 
# Perl 6 
 my $i_fh = open $input_path,  :r; # Returns Failure on error 
 my $o_fh = open $output_path, :w; # Returns Failure on error 

Because you can check for truthiness without any problem, you can use the result of an open in an if statement:

# Perl 6 
 if open($input_path,:r) -> $handle { 
     .say for $handle.lines; 
 } 
 else { 
     # gracefully handle the fact that the open() failed 
 } 

base

parent

Both use base and use parent have been replaced in Perl 6 by the is keyword, in the class declaration.

# Perl 5 
 package Cat; 
 use base qw(Animal); 
# Perl 6 
 class Cat is Animal {} 

Note that the Animal class must be known at compilation time prior to be able to inherit from it.

bigint bignum bigrat

No longer relevant.

Int is now arbitrary precision, as is the numerator of Rat (the denominator is limited to 2**64, after which it will automatically upgrade to Num to preserve performance). If you want a Rat with an arbitrary-precision denominator, FatRat is available.

constant

In Perl 6, constant is a declarator for variables, just like my, except the variable is permanently locked to the result of its initialization expression (evaluated at compile time).

So, change the => to =.

use constant DEBUG => 0; # Perl 5 
constant DEBUG = 0;      # Perl 6 
use constant pi => 4 * atan2(1, 1); # Perl 5 
 tau, pi, e, i; # built-in constants in Perl 6 
  τ, π, 𝑒        # and their unicode equivalents 

encoding

TODO Allows you to write your script in non-ascii or non-utf8

integer

Perl pragma to use integer arithmetic instead of floating point. There is no such equivalent in Perl 6. If you use native integers in your calculations, then this will be the closest thing.

my int $foo = 42; 
 my int $bar = 666; 
 say $foo * $bar;    # uses native integer multiplication 

lib

Manipulate where modules are looked up at compile time. The underlying logic is very different from Perl 5, but in most cases, use lib in Perl 6 works the same as in Perl 5.

mro

No longer relevant.

In Perl 6, method calls now always use the C3 method resolution order. If you need to find out parent classes of a given class, you can invoke the mro meta-method thusly:

say Animal.^mro;    # .^ indicates calling a meta-method on the object 

utf8

No longer relevant.

In Perl 6, source code is expected to be in utf8 encoding.

vars

Discouraged in Perl 5. See http://perldoc.perl.org/vars.html.

You should refactor your Perl 5 code to remove the need for use vars, before translating into Perl 6.

Command-line flags

See S19/commandline

Unchanged:

-c -e -h -I -n -p -S -T -v -V

-a

Change your code to use .split manually.

-F

Change your code to use .split manually.

-l

This is now the default behavior.

-M -m

Only -M remains. And, as you can no longer use the "no Module" syntax, the use of - with -M to "no" a module is no longer available.

-E

Since all features are already enabled, just use lowercase -e .

-d, -dt, -d:foo, -D, etc.

Replaced with the ++BUG metasyntactic option.

-s

Switch parsing is now done by the parameter list of the MAIN subroutine.

# Perl 5 
     #!/usr/bin/perl -s 
     if ($xyz) { print "$xyz\n" } 
 ./example.pl -xyz=5 
 5 
# Perl 6 
     sub MAIN( Int :$xyz ) { 
         say $xyz if $xyz.defined; 
     } 
perl6 example.p6 --xyz=5 
 5 
 perl6 example.p6 -xyz=5 
 5 

Removed.

Removed. See S19#Removed Syntactic Features.

This is now the default behavior.

File-related operations

Reading the lines of a text file into an array

In Perl 5, a common idiom for reading the lines of a text file goes something like this:

open my $fh, "<", "file" or die "$!"; 
 my @lines = <$fh>;                # lines are NOT chomped 
 close $fh; 

In Perl 6, this has been simplified to

my @lines = "file".IO.lines;  # auto-chomped

Do not be tempted to try slurping in a file and splitting the resulting string on newlines as this will give an array with a trailing empty element, which is one more than you probably expect (it's also more complicated), e.g.:

# initialize the file to read
spurt "test-file", q:to/END/;
first line
second line
third line
END
# read the file
my @lines = "test-file".IO.slurp.split(/\n/);
say @lines.elems;    #-> 4

If for some reason you do want to slurp the file first, then you can call the lines method on the result of slurp instead:

my @lines = "test-file".IO.slurp.lines;  # also auto-chomps

Trapping the standard output of executables.

Whereas in Perl 5 you would do:

my $arg = 'Hello'; 
 my $captured = `echo \Q$arg\E`; 
 my $captured = qx(echo \Q$arg\E); 

Or using String::ShellQuote (because \Q…\E is not completely right):

my $arg = shell_quote 'Hello'; 
 my $captured = `echo $arg`; 
 my $captured = qx(echo $arg); 

In Perl 6, you will probably want to run commands without using the shell:

my $arg = 'Hello';
my $captured = run('echo', $arg, :out).out.slurp-rest;
my $captured = run(«echo "$arg"», :out).out.slurp-rest;

You can also use the shell if you really want to:

my $arg = 'Hello';
my $captured = shell("echo $arg", :out).out.slurp-rest;
my $captured = qqx{echo $arg};

But beware that in this case there is no protection at all! run does not use the shell, so there is no need to escape the arguments (arguments are passed directly). If you are using shell or qqx, then everything ends up being one long string which is then passed to the shell. Unless you validate your arguments very carefully, there is a high chance to introduce shell injection vulnerabilities with such code.

Environment variables

Perl module library path

In Perl 5 one of the environment variables to specify extra search paths for Perl modules is PERL5LIB.

$ PERL5LIB="/some/module/lib" perl program.pl 

In Perl 6 this is similar, one merely needs to change a number! As you probably guessed, you just need to use PERL6LIB:

$ PERL6LIB="/some/module/lib" perl6 program.p6 

In Perl 5 one uses the ':' (colon) as a directory separator for PERL5LIB, but in Perl 6 one uses the ',' (comma). For example:

$ export PERL5LIB=/module/dir1:/module/dir2; 

but

$ export PERL6LIB=/module/dir1,/module/dir2; 

(Perl 6 does not recognize either the PERL5LIB or the older Perl environment variable PERLLIB.)

As with Perl 5, if you don't specify PERL6LIB, you need to specify the library path within the program via the use lib pragma:

use lib '/some/module/lib' 

Note that PERL6LIB is more of a developer convenience in Perl 6 (as opposed to the equivalent usage of PERL5LIB in Perl5) and shouldn't be used by module consumers as it could be removed in the future. This is because Perl 6's module loading isn't directly compatible with operating system paths.

Misc.

'0' is True

Unlike Perl 5, a string containing nothing but zero ('0') is True. As Perl 6 has types in core, that makes more sense. This also means the common pattern:

... if defined $x and length $x; # or just length() in modern perls 

In Perl 6 becomes a simple

... if $x; 

dump

Gone.

The Perl 6 design allows for automatic transparent saving-and-loading of compiled bytecode.

Rakudo supports this only for modules so far.

AUTOLOAD

The FALLBACK method provides similar functionality.

Importing specific functions from a module

In Perl 5 it is possible to selectively import functions from a given module like so:

use ModuleName qw{foo bar baz}; 

In Perl 6 one specifies the functions which are to be exported by using the is export role on the relevant subs and all subs with this role are then exported. Hence, the following module Bar exports the subs foo and bar but not baz:

unit module Bar; 
 
 sub foo($a) is export { say "foo $a" } 
 sub bar($b) is export { say "bar $b" } 
 sub baz($z) { say "baz $z" } 

To use this module, simply use Bar and the functions foo and bar will be available

use Bar; 
 foo(1);    #=> "foo 1" 
 bar(2);    #=> "bar 2" 

If one tries to use baz an "Undeclared routine" error is raised at compile time.

So, how does one recreate the Perl 5 behaviour of being able to selectively import functions? For this one needs to define an EXPORT sub inside the module which specifies the functions to be exported and remove the module Bar statement.

The module Bar now is merely a file called Bar.pm with the following contents:

use v6.c; 
 
 sub EXPORT(*@import-list) { 
     my %exportable-subs = 
         '&foo' => &foo, 
         '&bar' => &bar, 
         ; 
     my %subs-to-export; 
     for @import-list -> $import { 
         if grep $sub-name, %exportable-subs.keys { 
             %subs-to-export{$sub-name} = %exportable-subs{$sub-name}; 
         } 
     } 
     return %subs-to-export; 
 } 
 
 sub foo($a, $b, $c) { say "foo, $a, $b, $c" } 
 sub bar($a) { say "bar, $a" } 
 sub baz($z) { say "baz, $z" } 

Note that the subs are no longer explicitly exported via the is export role. We are defining an EXPORT sub which specifies the subs in the module we want to be available for export and then we are populating a hash containing the subs which will actually be exported. The @import-list is set by the use statement in the calling code thus allowing us to selectively import the subs made available by the module.

So, to import only the foo routine, we do the following in the calling code:

use Bar <foo>; 
 foo(1);       #=> "foo 1" 

Here we see that even though bar is able to be exported, if we don't explicitly import it, it's not available for use. Hence this causes an "Undeclared routine" error at compile time:

use Bar <foo>; 
 foo(1); 
 bar(5);       #!> "Undeclared routine: bar used at line 3" 

however, this will work

use Bar <foo bar>; 
 foo(1);       #=> "foo 1" 
 bar(5);       #=> "bar 5" 

Note also that baz remains unimportable even if specified in the use statement:

use Bar <foo bar baz>; 
 baz(3);       #!> "Undeclared routine: baz used at line 2" 

In order to get this to work, one obviously has to jump through many hoops. In the standard use-case where one specifies the functions to be exported via the is export role, Perl 6 automatically creates the EXPORT sub in the correct manner for you, so one should consider very carefully whether or not writing one's own EXPORT routine is worthwhile.

Importing groups of specific functions from a module

If you would like to export groups of functions from a module, you just need to assign names to the groups, and the rest will work automagically. When you specify is export in a sub declaration, you are in fact adding this subroutine to the :DEFAULT export group. But you can add a subroutine to another group, or to multiple groups:

unit module Bar; 
 sub foo() is export { }                   # added by default to :DEFAULT 
 sub bar() is export(:FNORBL) { }          # added to the FNORBL export group 
 sub baz() is export(:DEFAULT:FNORBL) { }  # added to both 

So now you can use the Bar module like this:

use Bar;                     # imports foo / baz 
 use Bar :FNORBL;             # imports bar / baz 
 use Bar :ALL;                # imports foo / bar / baz 

Note that :ALL is an auto-generated group that encompasses all subroutines that have an is export trait.

Core modules

Data::Dumper

In Perl 5, the Data::Dumper module was used for serialization, and for debugging views of program data structures by the programmer.

In Perl 6, these tasks are accomplished with the .perl method, which every object has.

# Given: 
     my @array_of_hashes = ( 
         { NAME => 'apple',   type => 'fruit' }, 
         { NAME => 'cabbage', type => 'no, please no' }, 
     ); 
 # Perl 5 
     use Data::Dumper; 
     $Data::Dumper::Useqq = 1; 
     print Dumper \@array_of_hashes; # Note the backslash. 
# Perl 6 
 say @array_of_hashes.perl; # .perl on the array, not on its reference. 

In Perl 5, Data::Dumper has a more complex optional calling convention, which allows for naming the VARs.

In Perl 6, placing a colon in front of the variable's sigil turns it into a Pair, with a key of the var name, and a value of the var value.

# Given: 
     my ( $foo, $bar ) = ( 42, 44 ); 
     my @baz = ( 16, 32, 64, 'Hike!' ); 
 # Perl 5 
     use Data::Dumper; 
     print Data::Dumper->Dump( 
         [     $foo, $bar, \@baz   ], 
         [ qw(  foo   bar   *baz ) ], 
     ); 
 # Output 
 #    $foo = 42; 
 #    $bar = 44; 
 #    @baz = ( 
 #             16, 
 #             32, 
 #             64, 
 #             'Hike!' 
 #           ); 
# Perl 6 
 say [ :$foo, :$bar, :@baz ].perl; 
 # OUTPUT: «["foo" => 42, "bar" => 44, "baz" => [16, 32, 64, "Hike!"]]␤» 

There is also a Rakudo-specific debugging aid for developers called dd (Tiny Data Dumper, so tiny it lost the "t"). This will print the .perl representation plus some extra information that could be introspected, of the given variables on STDERR:

# Perl 6 
 dd $foo, $bar, @baz; 
 # OUTPUT: «Int $foo = 42␤Int $bar = 44␤Array @baz = [16, 32, 64, "Hike!"]␤» 

Getopt::Long

Switch parsing is now done by the parameter list of the MAIN subroutine.

# Perl 5 
     use 5.010; 
     use Getopt::Long; 
     GetOptions( 
         'length=i' => \( my $length = 24       ), # numeric 
         'file=s'   => \( my $data = 'file.dat' ), # string 
         'verbose'  => \( my $verbose           ), # flag 
     ) or die; 
     say $length; 
     say $data; 
     say 'Verbosity ', ($verbose ? 'on' : 'off') if defined $verbose; 
 perl example.pl 
     24 
     file.dat 
 perl example.pl --file=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 
 perl example.pl --length=abc 
     Value "abc" invalid for option length (number expected) 
     Died at c.pl line 3. 
# Perl 6 
     sub MAIN( Int :$length = 24, :file($data) = 'file.dat', Bool :$verbose ) { 
         say $length if $length.defined; 
         say $data   if $data.defined; 
         say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
     } 
perl6 example.p6 
     24 
     file.dat 
     Verbosity off 
 perl6 example.p6 --file=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 perl6 example.p6 --length=abc 
     Usage: 
       c.p6 [--length=<Int>] [--file=<Any>] [--verbose] 

Note that Perl 6 auto-generates a full usage message on error in command-line parsing.

Automated Translation

A quick way to find the Perl 6 version of a Perl 5 construct, is to run it through an automated translator.

NOTE: None of these translators are yet complete.

Blue Tiger

This project is dedicated to automated modernization of Perl code. It does not (yet) have a web front-end, and so must be locally installed to be useful. It also contains a separate program to translate Perl 5 regexes into Perl 6.

https://github.com/Util/Blue_Tiger/

Perlito

Online Translator!

This project is a suite of Perl cross-compilers, including Perl 5-to-6 translation. It has a web front-end, and so can be used without installation. It only supports a subset of Perl 5 syntax so far.

http://fglock.github.io/Perlito/perlito/perlito5.html

Perl-ToPerl6

Jeff Goff's Perl::ToPerl6 module for Perl 5 is designed around Perl::Critic's framework. It aims to convert Perl5 to compilable (if not necessarily running) Perl 6 code with the bare minimum of changes. Code transformers are configurable and pluggable, so you can create and contribute your own transformers, and customize existing transformers to your own needs. You can install the latest release from CPAN, or follow the project live on GitHub. An online converter may become available at some point.

Other sources of translation knowledge

3 Perl 5 to Perl 6 guide - Overview

How do I do what I used to do?

These documents should not be mistaken for a beginner tutorial or a promotional overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Perl 5 background and for anyone porting Perl 5 code to Perl 6.

Perl 6 in a Nutshell

Perl 6 in a Nutshell provides a quick overview of things changed in syntax, operators, compound statements, regular expressions, command-line flags, and various other bits and pieces.

Syntactic differences

The Syntax section provides an overview of the syntactic differences between Perl 5 and Perl 6: how it is still mostly free form, additional ways to write comments, and how switch is very much a Perl 6 thing.

Operators in Perl 6

The Operators section guides you from the operators in Perl 5's perlop to the equivalent in Perl 6.

Functions in Perl 6

The Functions section describes all of the Perl 5 functions and their Perl 6 equivalent and any differences in behaviour. It also provides references to ecosystem modules that provide the Perl 5 behaviour of functions,either existing in Perl 6 with slightly different semantics (such as shift), or non-existing in Perl 6 (such as tie).

Special Variables in Perl 6

The Special Variables section describes if and how a lot of Perl 5's special (punctuation) variables are supported in Perl 6.

4 Perl 5 to Perl 6 guide - Functions

Builtin functions in Perl 5 to Perl 6

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 builtin functions with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document is an attempt to guide you from the functions in Perl 5's perlfunc document to their equivalents in Perl 6. For full documentation on the Perl 6 functions, follow the links in this document to their respective documentation.

One general comment: Perl 6 takes its objects a lot more seriously than Perl 5. In Perl 6, everything is an object, although the language is flexible enough to not force you to work in an object oriented manner if you do not wish to do so. What this does mean, however, is that a lot of things that are function calls of the form function(@args) are now also method calls of the form @args.function (In rare cases, there is only a method call). This should be obvious in the following text, but it probably behooves you to get into that frame of mind now.

Also, unless otherwise stated, the use of the term "function" here will mean a function in the style of func(@args), while "method" will refer to a function in the style of @args.func.

Alphabetical Listing of Perl Functions

Filetests

Perl 6 gives you a couple of options when it comes to file tests. You can do a smartmatch (~~) or you can call a method.

In Perl 6, you don't need to actually open a filehandle in the traditional way (although you can) to do a filetest. You can simply append .IO to the filename. For instance, here is how to check if a file is readable using smartmatch:

'/path/to/file'.IO ~~ :r

You can, of course, use an already opened filehandle. Here, using the filehandle $fh, is an example, using the method syntax for the file test:

$fh.r 

Most of the former filetests have colon equivalents for use with smartmatch:

:e Exists
:d Directory
:f File
:l Symbolic link
:r Readable
:w Writable
:x Executable
:s Size
:z Zero size

All of these tests can be used as methods (without the colon).

Three tests, however, only have method equivalents:

$fh.modified; # -M $fh 
 $fh.accessed; # -A $fh 
 $fh.changed;  # -C $fh 

The remaining filetests in Perl 5 do not appear to be implemented in Perl 6.

The documentation for this can be found at File test operators.

There is more information on reading and writing files at io. Also, the section on open() below may be helpful.

The Perl 6 ecosystem has a module P5-X which exports the behaviour as much as possible in Perl 6.

abs

Works as a function (abs($x)), but also as a method. One gotcha, however - method calls bind more tightly than -, so, for example, -15.abs evaluates as -(15.abs) giving you -15. In this example, you would have to do something like (-15).abs.

abs also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .abs rather than simply abs.

The Perl 6 ecosystem has a module P5math which exports an abs function that mimics the original Perl 5 behaviour as much as possible.

accept

accept is a method you can call on a server, e. g. $server.accept(). Instead of returning a packed address, it returns a socket, most likely an IO::Socket object of some sort.

alarm

alarm() is no more. But it is possible to have code execute after a certain time has elapsed, or at a given time:

Promise.in(5).then: { say "five seconds have passed" }

Promise.at(now + 5).then: { say "five seconds have passed" }

In Perl 6, this does *not* involve any (dummy) signals.

atan2

Available as a function as well as being able to be used as a method. For instance, these are equivalent:

atan2(100);
100.atan2;

bind

[NEEDS FURTHER RESEARCH] No sign of a socket-related bind() in Perl 6. At a guess, whatever socket binding is needed happens when you create a new socket object.

binmode

Instead of this, you would use :bin as the file mode when opening the socket. E. g. my $fh = open("path/to/file", :bin);

bless

With the changes in class creation in Perl 6, this may find less use than in Perl 5, and is a method as well as a function. The Perl 6 docs say "Creates a new object of the same type as the invocant, uses the named arguments to initialize attributes, and returns the created object." If you're porting a module from Perl 5 to Perl 6, it's quite possible you'll want to use new for creating objects rather than bless, although there may be some situations in which the latter may still be useful.

break

Not in Perl 6. For breaking out of given blocks, you should probably take a look at proceed and succeed here.

caller

There are a couple different ways to get at caller information in Perl 6. The basic functionality is provided through callframe now. However, Perl 6 constructs call frames for regular blocks, not just for subroutines, so there are more frames to look through. The following will retrieve the basic information that caller can return:

my $frame   = callframe(0); # OR just callframe()
my ($subroutine, $package);
if $frame.code ~~ Routine {
    $subroutine = $frame.code.name;
    $package    = $frame.code.package;
}
my $file    = $frame.file;
my $line    = $frame.line;

Many of the other details returned by caller are specific to Perl 5 and have no meaning in Perl 6.

You can also get some of the information for the current frame or routine frame by using the dynamic variables &?ROUTINE, &?BLOCK, $?PACKAGE, $?FILE, and $?LINE. For many purposes, Backtrace may provide an easier way to browse through the call stack.

The Perl 6 ecosystem has a module P5caller which exports a caller function that mimics the original Perl 5 behaviour as much as possible.

chdir

Works as it does in Perl 5 but must take an argument. The behaviour of chdir() (with regards to looking at HOME and LOGDIR) is not supported.

In Perl 6, chdir only changes the $*CWD dynamic variable. It does not actually change the default directory from the OS's point of view; the special dynamic-variable routine &*chdir can be used for that, if needed.

This is done this way, because there is no concept of a "default directory per OS thread". And since Perl 6 does not fork, but only does threading, it was felt that the "current directory" concept should be in the $*CWD dynamic variable, which can be lexically scoped, and thus can be thread-safe.

The Perl 6 ecosystem has a module P5chdir which exports a chdir function that mimics the original Perl 5 behaviour as much as possible, including looking at HOME and LOGDIR.

chmod

Functions as under Perl 5, with the difference that octal numbers are represented differently (0o755 rather than 0755). You may also use it as a method, e. g. $fh.chmod(0o755).

chomp

The behavior of chomp is different than in Perl 5. It leaves the target unaffected and returns a copy of the target with a final logical newline removed, e.g. $x = "howdy\n";$y = chomp($x); results in $x containing "howdy\n" and $y containing "howdy". Also works as a method, e.g. $y = $x.chomp. As with many other methods, also works with assignment to modify the target in place, e.g. $x.=chomp results in $x containing "howdy".

Note that chomp() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chomp which exports a chomp function that mimics the original Perl 5 behaviour as much as possible.

.head2 chop

As with chomp, in Perl 6, this returns the chopped string, rather than chopping in place. I. e. $x = "howdy";$y = chop($x); results in $x being "howdy" and $y being "howd". Also works as a method: $y = $x.chop.

Note that chop() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chomp which exports a chop function that mimics the original Perl 5 behaviour as much as possible.

.head2 chown

chown is not in Perl 6.

chr

Similar to the Perl 5 version, coerces the target to an integer, and uses that as a Unicode code point to return the relevant character. Can be used as a function and a method:

chr(65); # "A"
65.chr;  # "A"

Note that chr() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chr which exports a chr function that mimics the original Perl 5 behaviour as much as possible.

chroot

chroot is not in Perl 6.

close

As in Perl 5, closes a filehandle. Returns a boolean value. Both close $fh and $fh.close will work.

Note that close() (without arguments) is not supported in Perl 6.

closedir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a closedir function that mimics the original Perl 5 behaviour as much as possible.

connect

Use connect from IO::Socket::Async for an asynchronous socket or create a IO::Socket::INET socket for a synchronous one.

continue

Instead of a continue block, you should use a NEXT block. The closest analog to a bare continue; in Perl 5 appears to be proceed/succeed.

cos

Works as in Perl 5.

cos also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .cos rather than simply cos.

The Perl 6 ecosystem has a module P5math which exports a cos function that mimics the original Perl 5 behaviour as much as possible.

crypt

Not available in Perl 6.

The Perl 6 ecosystem has a module P5math which exports a crypt function that mimics the original Perl 5 behaviour as much as possible.

dbm functions

These functions have largely been superseded in Perl 5, and are unlikely to ever turn up in Perl 6 (although any assumptions about the Perl 6 database implementation may be premature).

defined

Probably does what you expect, but technically it returns False on the type object, and True otherwise. This may make more sense when you realize that $num.perl is the type Any if you haven't assigned anything to it, and the assigned value if you have. Can, of course be used as a method: $num.defined. And any newly created class can have its own .defined method, thereby deciding how and when it should be considered undefined.

Note that defined() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5defined which exports a defined function that mimics the original Perl 5 behaviour as much as possible.

delete

Perl 6 replaces this with the new adverb syntax, specifically the :delete adverb. E. g. my $deleted_value = %hash{$key}:delete; and my $deleted_value = @array[$i]:delete;.

die

Works similarly to the Perl 5 version, but Perl 6's Exception mechanism may give you more power and flexibility than is available in Perl 5. See exceptions. To omit the stacktrace and location, like Perl 5's die "...\n", use:

note "...";
exit 1;

do

Similar to the Perl 5 version. Note that there must be a space between the do and the block.

Has been replaced in Perl 6 by EVALFILE.

dump

According to S29, dump has been... dumped.

each

There is no exact equivalent, but you can use %hash.kv which returns a list of keys and values. For example: for %hash.kv -> $k, $v { say "$k: $v" }

Incidentally, what we have there with the -> is called a pointy block and, though there are a number of examples in the documentation, there doesn't seem to be a really clear explanation of how they work. https://design.perl6.org/S04.html#The_for_statement may be of some help here, as well as the design document at https://design.perl6.org/S06.html#%22Pointy_blocks%22. There is also some information at https://en.wikibooks.org/wiki/Perl_6_Programming/Blocks_and_Closures#Pointy_Blocks

The Perl 6 ecosystem has a module P5each which exports an each function that mimics the original Perl 5 behaviour as much as possible.

eof

In Perl 6, this is not usable as a function, but only as a method. I. e. $filehandle.eof. Returns True if at end of file.

eval

The closest replacment is the EVAL function. However, this function has to be allowed explicitly using a pragma to work in the same way. Note that EVAL does not do any exception handling!

evalbytes

No equivalent.

exec

Nothing in Perl 6 exactly replicates the Perl 5 exec. shell and run are similar to Perl 5's system, but exec's behavior of not returning after executing a system command would have to be emulated by something like shell($command);exit(); or possibly exit shell($command);.

Neither of these workarounds have the behavior (on Unix-like systems) of replacing your Perl program's process with the new program; notably, they will not work for the practice in some long-running daemons of periodically redoing exec on themselves to reset their state or force operating-system cleanup. Nor will they serve exec's function of returning stale resources to the operating system.

If you want exec for these behaviors, you can use an exec* function via the NativeCall interface. Consult your operating system manual pages for exec (or other similarly-named calls such as execl, execv, execvp, or execvpe). (Beware: these calls are not generally portable between Unix-like operating system families.)

exists

In Perl 6, this is not a function, but an adverb:

%hash{$key}:exists; 
 @array[$i]:exists; 

exit

Appears to do the same thing as in Perl 5.

exp

Same as in Perl 5.

exp also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .exp rather than simply exp.

The Perl 6 ecosystem has a module P5math which exports an exp function that mimics the original Perl 5 behaviour as much as possible.

fc

Looks like it does the same thing as in Perl 5 except that calling it without arguments is not supported in Perl 6.

The Perl 6 ecosystem has a module P5fc which exports a fc function that mimics the original Perl 5 behaviour as much as possible.

fcntl

Appears not to be in Perl 6.

__FILE__

Replaced by $?FILE which is slightly different from __FILE__ in that it is always an absolute path, rather than a relative one in the Perl 5 case.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __FILE__ term that mimics the original Perl 5 behaviour as much as possible.

fileno

The native-descriptor method on IO::Handle returns the equivalent of fileno.

The Perl 6 ecosystem has a module P5fileno which exports a fileno function that mimics the original Perl 5 behaviour as much as possible.

flock

Currently unimplemented.

fork

There is no built-in fork function. While it's possible to call it using NativeCall, it's highly unlikely that the resulting process will be usable.

Perl 6 provides extensive support for, and internally uses, threads. However, fork only clones the thread that called fork, resulting in a process that will be missing its other threads, which will have been in unknown states and probably holding locks. Even if a Perl 6 program doesn't knowingly start any threads, the compiler may create some of its own in the process of precompilation, and the VMs that Perl 6 runs on also create their own internal worker threads for doing things like optimization and GC in the background. Thus, the presence of threads is pretty much assured, and there's no reasonable way to make fork reliably work in this case.

formats

Perl 6 does not have built-in formats.

getc

Reads a single character from the input stream as in Perl 5. May now also be used as a method: $filehandle.getc

getpeername

S29 lists it, but the implementation does not seem clear or, for that matter, implemented.

getpgrp

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getpgrp function that mimics the original Perl 5 behaviour as much as possible.

getppid

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getppid function that mimics the original Perl 5 behaviour as much as possible.

getpriority

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getpriority function that mimics the original Perl 5 behaviour as much as possible.

get and set functions

The Perl 6 ecosystem has a module P5getpwnam which exports the endpwent, getlogin, getpwent, getpwnam, getpwuid and setpwent functions that mimic the original Perl 5 behaviour as much as possible.

The Perl 6 ecosystem has a module P5getgrnam which exports the endgrent, getgrent, getgrgid, getgrnam and setgrent functions that mimic the original Perl 5 behaviour as much as possible.

The Perl 6 ecosystem has a module P5getnetbyname which exports the endnetent, getnetent, getnetbyaddr, getnetbyname and setnetent functions that mimic the original Perl 5 behaviour as much as possible.

The Perl 6 ecosystem has a module P5getservbyname which exports the endservent, getservent, getservbyname, getservbyport and setservent functions that mimic the original Perl 5 behaviour as much as possible.

The Perl 6 ecosystem has a module P5getprotobyname which exports the endprotoent, getprotoent, getprotobyname, getprotobynumber and setprotoent functions that mimic the original Perl 5 behaviour as much as possible.

[NEEDS FURTHER RESEARCH] Apparently this range of functions are to be handled by roles like User, Group, etc.

getsock*

[NEEDS FURTHER RESEARCH] These are likely implemented by some kind of IO::Socket object, but details are unclear.

glob

Not available in core, although some of the functionality is offered by dir routine and its test argument.

See IO::Glob module in ecosystem

gmtime

Like the various parts of localtime, gmtime's functionality appears to in the DateTime object. To get a UTC version of a DateTime object for the current time, for instance, use my $gmtime = DateTime.now.utc.

The Perl 6 ecosystem has a module P5localtime which exports a gmtime function that mimics the original Perl 5 behaviour as much as possible.

goto

The syntax for goto LABEL is already accepted, but the runtime part of goto is not yet implemented. So this will result in a runtime error:

FOO: goto FOO; # Label.goto() not yet implemented. Sorry.

grep

Still in Perl 6, with the caveat that the block form now requires a comma after the block. I.e. @foo = grep { $_ = "bars" }, @baz. Can also be used as a method: @foo = @bar.grep(/^f/)

hex

In Perl 6 an expression must be specified.

Replaced by the adverbial form :16. E. g. :16("aF") returns 175.

Alternately, the same result can be achieved by using the .base method: 0xaF.base(10)

It just so happens that .Str defaults to base 10, so if you just say 0xaF, that will also print 175, but that may not be immediately obvious, so may not be the best way to go for this.

The Perl 6 ecosystem has a module P5hex which exports a hex function that mimics the original Perl 5 behaviour as much as possible.

import

Was never a builtin function in Perl 5 in the first place. In Perl 6, typically, one declares functions as exportable or not, and all the exportable ones are exported. Nevertheless, selective importing is possible, but beyond the scope of this document. For details, see this section.

index

Works as in Perl 5. Can also now be used as a method: "howdy!".index("how"); # 0. Main difference with Perl 5 is that Nil is returned instead of -1 when the substring is not found. This is very useful in combination with the with command:

with index("foo","o") -> $index {
    say "Found it at $index";
}
else {
    say "Not found"
}

The Perl 6 ecosystem has a module P5index which exports an index function that mimics the original Perl 5 behaviour as much as possible.

int

There is a truncate function in Perl 6 (also usable as a method) that does what Perl 5's int does. You may want to use that as a direct translation of Perl 5 code, but in Perl 6, you can just as easily call the .Int method on the number. 3.9.Int; # 3 and 3.9.truncate are equivalent.

Please note that int does have a meaning in Perl 6. It is type that can be used to indicate a native integer:

my int $a = 42;   # a native integer, similar to Perl 5's integer values

int also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .int rather than simply int.

The Perl 6 ecosystem has a module P5math which exports an int function that mimics the original Perl 5 behaviour as much as possible.

ioctl

Currently unimplemented in Perl 6.

join

Works as in Perl 5, and also works as a method: @x.join(",")

keys

Works as in Perl 5, and can also be used as a method: %hash.keys

kill

No pre-defined core alternative exists. A non-portable method can be to use NativeCall:

use NativeCall;
sub kill(int32, int32) is native {*};
kill $*PID, 9; # OUTPUT: «Killed␤»

To kill processes that were started by creating a Proc::Async, use Proc::Async.kill method.

last

Same as in Perl 5.

lc

Works as in Perl 5, and also as a method: "UGH".lc. In Perl 6 an expression must be specified.

The Perl 6 ecosystem has a module P5lc which exports an lc function that mimics the original Perl 5 behaviour as much as possible.

lcfirst

Does not exist in Perl 6.

The Perl 6 ecosystem has a module P5lcfirst which exports an lcfirst function that mimics the original Perl 5 behaviour as much as possible.

length

Replaced by chars, typically used as a method ($string.chars), but also works as a function.

The Perl 6 ecosystem has a module P5length which exports an length function that mimics the original Perl 5 behaviour as much as possible.

__LINE__

Replaced by $?LINE.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __LINE__ term that mimics the original Perl 5 behaviour as much as possible.

See link

listen

Not clearly documented, but it appears that listen will be a method you would call on some variety of IO::Socket object.

local

The Perl 6 equivalent is temp. Unlike local, however, the value of the given variable is not immediately unset: it retains its original value until assigned to.

localtime

Most of the functionality of localtime is found in DateTime. The specific parts of localtime can be found as follows:

my $d = DateTime.now; 
 my $sec  = $d.second; # Potentially includes fractional seconds 
 my $min  = $d.minute; 
 my $hour = $d.hour; 
 my $mday = $d.day-of-month; # or $d.day; 1..31 
 my $mon  = $d.month; # 1..12 
 my $year = $d.year; 
 my $wday = $d.day-of-week; # 1 => Monday, 2 => Tuesday, etc. 
 my $yday = $d.day-of-year; # 1..366 

Please note that ranges are not 0-based in Perl 6, as shown in the comments in the example.

There does not currently appear to be a way to get Perl 5's $isdst. Also, the result of scalar(localtime) that Perl 5 provides is not available. $d.Str will give something along the lines of "2015-06-29T12:49:31-04:00".

The Perl 6 ecosystem has a module P5localtime which exports a localtime function that mimics the original Perl 5 behaviour as much as possible.

lock

There currently is no equivalent for this In Perl 6. There is a Lock class for creating a Lock object, that can be locked/unlocked as needed. But such a lock does not refer to any external objects.

log

Same as in Perl 5.

log also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .log rather than simply log.

The Perl 6 ecosystem has a module P5math which exports a log function that mimics the original Perl 5 behaviour as much as possible.

lstat

Likely implemented somewhere in one of the IO classes in Perl 6, but it is not clear where at this time.

m//

Regular expression syntax is somewhat different in Perl 6, but the match operator still exists. If you're trying to rewrite some Perl 5 code, the most important difference is that =~ is replaced by the smartmatch operator, ~~. Similarly, !~ is replaced by !~~. Options for regex operators are adverbs and are complicated. For details, see Adverbs

map

As a function, the only difference between Perl 5 and Perl 6 is that, if you're using a block, the block must be followed by a comma. Can also be used as a method: @new = @old.map: { $_ * 2 }

mkdir

Works as in Perl 5. When giving a multi-level directory specification, it will automatically create non-existing intermediate directories with the same MASK (similar to what "make_path" does of the File::Path module in Perl 5).

The zero argument (implicit $_) version is not permitted in Perl 6.

msg*

Not builtins in Perl 6. May appear in an external module at some point. Maybe.

my

Works as in Perl 5.

next

The same in Perl 6.

no

In Perl 6, this is usable for pragmas such as strict, but not for modules or versions.

oct

Replaced by the adverbial form :8. E. g. :8("100") returns 64.

If you want to deal with strings that start in 0x, 0o, or 0b, you can just use the prefix:<+> operator.

The Perl 6 ecosystem has a module P5hex which exports an oct function that mimics the original Perl 5 behaviour as much as possible.

open

The most obvious change from Perl 5 is the file mode syntax. To open a file for reading only, you would say open("file", :r). For write- only, read-write, and append, you would use :w, :rw, and :a respectively. There are also options for encoding and how the filehandle deals with newlines. Details here.

Another important change is that filehandles don't get automatically closed on scope exit. It's necessary to call close explicitly.

opendir

No replacement. See &dir / IO::Path.dir for alternatives.

The Perl 6 ecosystem has a module P5opendir which exports an opendir function that mimics the original Perl 5 behaviour as much as possible.

ord

Same as in Perl 5. May be used as a method: "howdy!".ord; # 104

Note that ord() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chr which exports a ord function that mimics the original Perl 5 behaviour as much as possible.

our

The same in Perl 6.

pack

Available in Perl 6 when use experimental :pack has been specified in the scope where pack needs to be called. The template options are currently more restricted than they are in Perl 5. The current documented list can be found at unpack.

The Perl 6 ecosystem has a module P5pack which exports a pack function that mimics the original Perl 5 behaviour as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.

package

S10 indicates that package can be used in Perl 6, but only with a block. I. e. package Foo { ... } means that the code within the block would be in package Foo. There is a special case where a declaration of the form package Foo; as the first statement in a file indicates that the rest of the file is Perl 5 code, but the usefulness of this is unclear. In fact, as modules and classes are declared with distinct keywords (such as class), it's unlikely you will use package directly in Perl 6.

__PACKAGE__

Replaced by $?PACKAGE which is slightly different from __PACKAGE__ in that it is the actual package object. You should call the .^name method on it to get a string.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __PACKAGE__ term that mimics the original Perl 5 behaviour as much as possible.

pipe

Depending on your needs, see Channel to shuttle data between threads (and Concurrency tutorial for other options), or see Proc type for piping to and from processes.

pop

Works in Perl 6, and can also be used as a method. I. e. my $x = pop @a; and my $x = @a.pop; are equivalent.

The non-parameter version of pop does not exist. Also, if the array is empty, a Failure will be returned in Perl 6, which will throw if the value is actually used in a significant way.

If you are using only defined values in your array, you can use the with function to handle this case:

with pop @array -> $popped { 
     say "popped '$popped' of the array"; 
 } 
 else { 
     say "there was nothing to pop"; 
 } 

The Perl 6 ecosystem has a module P5push which exports a pop function that mimics the original Perl 5 behaviour as much as possible.

pos

Not available in Perl 6. The closest equivalent is the :c adverb, which defaults to $/.to if $/ is true, and 0 if it isn't. For information on :c, see Continue.

print

print can be used as a function in Perl 6, writing to standard out. To use print as a function with a filehandle instead of standard out, you can use a method call: $fh.print("howdy!")

The Perl 6 ecosystem has a module P5print which exports a print function that mimics the original Perl 5 behaviour as much as possible.

printf

Perl 6 version is similar; see sprintf for details on acceptable format directives. To print to a filehandle other than STDOUT, use the .printf method on that filehandle.

The Perl 6 ecosystem has a module P5print which exports a printf function that mimics the original Perl 5 behaviour as much as possible.

prototype

Not available in Perl 6. The closest equivalent is .signature. E. g. say &sprintf.signature results in "(Cool $format, *@args)".

push

Works as in Perl 5, as well as being available as a method: @a.push("foo");. Note: the flattening behaviour is different in Perl 6: @b.push: @a will push @a into @b as a single element. See also the append method.

Also note that push in Perl 6 returns the array to which was pushed, contrary to Perl 5 where it returns the new number of elements.

The Perl 6 ecosystem has a module P5push which exports a push function that mimics the original Perl 5 behaviour as much as possible.

quoting

These survive the transition to Perl 6. Some notes:

q/.../;  # is still equivalent to using single quotes. 
 qq/.../; # is still equivalent to using double quotes. 
 qw/.../; # is more commonly rendered as C<< <...> >> in Perl 6. 

There are some added quoting constructs and equivalents, as explained at quoting.

Has been replaced by rx/.../.

No direct equivalent, i.e. nothing that just returns the string with all the ASCII non-word characters backslashed. In regexes, however, using $foo will treat $foo as a literal string, and using <$foo> will interpret the contents of $foo as regex code. Note that the angle brackets are doing something different here than they do outside a regex. For more information on this, see https://design.perl6.org/S05.html#Extensible_metasyntax_(%3C...%3E)

The Perl 6 ecosystem has a module P5quotemeta which exports a quotemeta function that mimics the original Perl 5 behaviour as much as possible.

rand

rand by itself works as it does in Perl 5, but you can no longer give it an argument. You can, however, use it as a method on a number to get that behavior. I. e. the Perl 5 rand(100) is equivalent to 100.rand in Perl 6. Additionally, you can get a random integer by using something like (^100).pick. For why you are able to do that, see ^ operator and pick.

The Perl 6 ecosystem has a module P5math which exports a rand function that mimics the original Perl 5 behaviour as much as possible.

read

read is found in IO::Handle and IO::Socket in Perl 6. It reads the specified number of bytes (rather than characters) from the relevant handle or socket. The use of an offset available in Perl 5 is not documented to exist at this time.

readdir

Not a builtin function. To iterate through the contents of a directory, take a look at dir routine.

The Perl 6 ecosystem has a module P5opendir which exports a readdir function that mimics the original Perl 5 behaviour as much as possible.

readline

Not available in Perl 6. You most likely want to use the .lines method in some way. For more detailed information on reading from files, see io.

Appears to be gone from Perl 6. There is a method resolve in IO::Path that will follow symlinks if the OS / Filesystem supports them.

The Perl 6 ecosystem has a module P5readlink which exports a readlink function that mimics the original Perl 5 behaviour as much as possible.

readpipe

Doesn't appear to be working in Perl 6, but qx// is functional, so it might be lurking around in some class that isn't obvious.

recv

Appears to be in IO::Socket. Not extensively documented at this time.

redo

Unchanged in Perl 6.

ref

Gone. To quote S29, "If you really want the type name, you can use $var.WHAT.^name.

The Perl 6 ecosystem has a module P5ref which exports a ref function that mimics the original Perl 5 behaviour as much as possible.

rename

Still available in Perl 6.

requires

No equivalent.

reset

No equivalent.

The Perl 6 ecosystem has a module P5reset which exports a reset function that mimics the original Perl 5 behaviour as much as possible.

return

Appears to be available in Perl 6, although not clearly documented.

reverse

In Perl 6, this only reverses the elements of a list. reverse(@a) or @a.reverse. To reverse the characters in a string, use the .flip method.

reverse without parameters is not supported in Perl 6.

The Perl 6 ecosystem has a module P5reverse which exports a reverse function that mimics the original Perl 5 behaviour as much as possible.

rewinddir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5rewinddir which exports a rewinddir function that mimics the original Perl 5 behaviour as much as possible.

rindex

Works as in Perl 5, and may also be used as a method. E. g. $x = "babaganush";say $x.rindex("a"); say $x.rindex("a", 3); # 5, 3. Main difference with Perl 5 is that Nil is returned instead of -1 when the substring is not found. This is very useful in combination with the with command:

with index("foo","o") -> $index {
    say "Found it at $index";
}
else {
    say "Not found"
}

The Perl 6 ecosystem has a module P5index which exports a rindex function that mimics the original Perl 5 behaviour as much as possible.

rmdir

Works in Perl 6 and can also be used as a method. rmdir "Foo"; and "Foo".IO.rmdir; are equivalent.

s///

Regular expression syntax is somewhat different in Perl 6, but the substitution operator exists. If you're trying to rewrite some Perl 5 code, the most important difference is that =~ is replaced by the smartmatch operator, ~~. Similarly, !~ is !~~. Options for regex operators are adverbs and are complicated. For details, see Adverbs page

say

say can be used as a function, defaulting to standard out. To use say as a function with a filehandle instead of standard out, you need to put a colon after the filehandle. I. e. say $fh: "Howdy!". The use of the colon as an "invocant marker" here is discussed at https://design.perl6.org/S03.html#line_4019. Alternately, you can use a method call: $fh.say("howdy!")

The Perl 6 ecosystem has a module P5print which exports a say function that mimics the original Perl 5 behaviour as much as possible.

scalar

Gone. Apparently "very" gone.

Some functions of the modules created for the CPAN Butterfly Plan accept a :scalar named parameter to indicate that the scalar behaviour of the function is required.

seek

Not documented in a any real way yet, but listed as a method of the IO::Handle class.

The Perl 6 ecosystem has a module P5seek which exports a seek function that mimics the original Perl 5 behaviour as much as possible.

seekdir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a seekdir function that mimics the original Perl 5 behaviour as much as possible.

select

"[S]elect as a global concept is dead." When I asked around about select, I was told that $*OUT and such are overridable in dynamic scope, and that IO::Capture::Simple (at https://github.com/sergot/IO-Capture-Simple) may be of use for something you might be doing with the value of select.

semctl

No longer in core.

semget

No longer in core.

semop

No longer in core.

send

Can be found in the IO::Socket class.

setpgrp

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a setpgrp function that mimics the original Perl 5 behaviour as much as possible.

setpriority

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a setpriority function that mimics the original Perl 5 behaviour as much as possible.

setsockopt

Not documented, but probably hiding in an IO class somewhere.

shift

Works in Perl 6, and can also be used as a method. I. e. my $x = shift @a; and my $x = @a.shift; are equivalent.

The non-parameter version of shift does not exist. Also, if the array is empty, a Failure will be returned in Perl 6, which will throw if the value is actually used in a significant way.

If you are using only defined values in your array, you can use the with function to handle this case:

with shift @array -> $shifted { 
     say "shifted '$shifted' of the array"; 
 } 
 else { 
     say "there was nothing to shift"; 
 } 

The Perl 6 ecosystem has a module P5shift which exports a shift function that mimics the original Perl 5 behaviour as much as possible.

shm*

Gone from the core. May turn up in a module somewhere.

shutdown

Not documented, but likely moved into IO::Socket.

sin

Same as in Perl 5.

sin also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .sin rather than simply sin.

The Perl 6 ecosystem has a module P5math which exports a sin function that mimics the original Perl 5 behaviour as much as possible.

sleep

Still works as in Perl 5, but is not limited to integer values for seconds. And it always returns Nil.

If you're interested in the return values of sleep to ensure sleeping until a specified time, then you should use sleep-until in Perl 6 (which takes an Instant).

If you're interested in running some code every N seconds, and you don't care on which thread it runs, you should probably use react and whenever with a Supply.interval.

The Perl 6 ecosystem has a module P5sleep which exports a sleep function that mimics the original Perl 5 behaviour as much as possible.

sockets

Not currently documented, but will likely wind up in IO::Socket.

sort

sort exists in Perl 6, but is somewhat different. $a and $b are no longer special (see Special Variables) and sort routines no longer return positive integers, negative integers, or 0, but rather Order::Less, Order::Same, or Order::More objects. See sort for details. May also be used as a method I. e. sort(@a) is equivalent to @a.sort.

splice

Available in Perl 6. Can also be used as a method. splice(@foo, 2, 3, <M N O P>); is equivalent to @foo.splice(2, 3, <M N O P>); .

split

Works mostly as in Perl 5. There are some exceptions, though. To get the special behavior of using the empty string, you must actually use the empty string - the special case of the empty pattern // being treated as the empty string does not apply. If you use a regex for the split, it will use the regex, while a literal string will be treated literally. If you wish to have the delimiters included in the resulting list, you need to use the named parameter :all, like this: split(';', "a;b;c", :all) # a ; b ; c Empty chunks are not removed from the result list as they are in Perl 5. For that behavior, see comb. Details on split are here. Unsurprisingly, split also now works as a method: "a;b;c".split(';')

The zero argument version must now be called with an explicit empty string, as described above.

sprintf

Works as in Perl 5. The formats currently available are:

% a literal percent sign
c a character with the given codepoint
s a string
d a signed integer, in decimal
u an unsigned integer, in decimal
o an unsigned integer, in octal
x an unsigned integer, in hexadecimal
e a floating-point number, in scientific notation
f a floating-point number, in fixed decimal notation
g a floating-point number, in %e or %f notation
X like x, but using uppercase letters
E like e, but using an uppercase "E"
G like g, but with an uppercase "E" (if applicable)

Compatibility:

i a synonym for %d
D a synonym for %ld
U a synonym for %lu
O a synonym for %lo
F a synonym for %f

Perl 5 (non-)compatibility:

n produces a runtime exception
p produces a runtime exception

There are modifiers for integers, but they're mainly no-ops, as the semantics aren't settled:

h interpret integer as native "short" (typically int16)
l interpret integer as native "long" (typically int32 or int64)
ll interpret integer as native "long long" (typically int64)
L interpret integer as native "long long" (typically uint64)
q interpret integer as native "quads" (typically int64 or larger)

sqrt

Same as in Perl 5.

sqrt also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .sqrt rather than simply sqrt.

The Perl 6 ecosystem has a module P5math which exports a sqrt function that mimics the original Perl 5 behaviour as much as possible.

srand

Available in Perl 6.

stat

Unlikely to be implemented as a built in function since it's POSIX specific, but available through the NativeCall interface.

state

Available in Perl 6, see state.

study

study is no more.

The Perl 6 ecosystem has a module P5study which exports a study function that mimics the original Perl 5 behaviour as much as possible.

sub

Unsurprisingly, we still have subroutines! You can have a signature in your subroutine which allows you to specify arguments. Nevertheless, in the absence of a signature (and only in the absence of a signature), @_ still contains what is passed to the function. So, in theory, you don't need to change that aspect of a function if porting from Perl 5 to Perl 6 (although you should probably consider the option of using a signature). For all the gory details, see functions.

__SUB__

Replaced by &?ROUTINE which is slightly different from __SUB__ in that it is the actual Sub (or Method) object. You should call the .name method on it to get a string.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __SUB__ term that mimics the original Perl 5 behaviour as much as possible.

substr

Can be used as a function or a method. substr("hola!", 1, 3) and "hola!".substr(1, 3) both return "ola".

See symlink.

syscall

Not a builtin in Perl 6. Most likely out in a module somewhere, but it's currently unclear where.

sys*

As with the non-sys versions of these functions, are probably lurking in the IO classes somewhere.

system

For this, you probably want (run) or (shell routine).

syswrite

As with sysopen and friends, this has moved into the IO classes.

tell

As a method on IO::Handle.

telldir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a telldir function that mimics the original Perl 5 behaviour as much as possible.

tie

The Perl 6 alternative to tying a scalar, is the Proxy container. For example:

sub lval() {
  Proxy.new(
    FETCH => method () { ...},
    STORE => method ($new) { ... }
  )
}

This makes lval a left-value sub. Whenever the value is requested, the FETCH method is called. And whenever it is used in an assignment, the STORE method is called.

For arrays and hashes (objects that do the Positional and/or Associative role), one only needs to provide the methods that these roles require to get the functionality that tie provides in Perl 5. These are documented in the Subscripts section.

The Perl 6 ecosystem has a module P5tie which exports tie / tied functions that mimics the original Perl 5 behaviour as much as possible.

time

Number of seconds since epoch (as an Int), same as in Perl 5.

times

Not available in Perl 6.

The Perl 6 ecosystem has a module P5times which exports a times function that mimics the original Perl 5 behaviour as much as possible.

tr///

Works similarly to how it does in Perl 5. The one caveat is that ranges are specified differently. Instead of using a range "a-z", you would use "a..z", i.e. with Perl's range operator. In Perl 6, tr/// has a method version, called trans, which offers a few additional features.

Perl 5's /r flag is instead implemented as TR/// operator. The y/// equivalent does not exist.

truncate

Not currently implemented (2018.04).

uc

Works as a function and a method. uc("ha") and "ha".uc both return "HA". There is no support for the parameterless version.

The Perl 6 ecosystem has a module P5lc which exports a uc function that mimics the original Perl 5 behaviour as much as possible.

ucfirst

Perl 6 has done away with ucfirst. The title case function tc probably does what you need.

The Perl 6 ecosystem has a module P5lcfirst which exports a ucfirst function that mimics the original Perl 5 behaviour as much as possible.

undef

There is no undef in Perl 6. You can't undefine a function, and the closest equivalent value is probably Nil, but you'll likely have no use for that.

If you were using something like (undef, $file, $line) = caller;, you would just get the filename and line number directly in Perl 6 instead of discarding the first result of caller. caller has been replaced by callframe in Perl 6, so the equivalent statement would be ($file, $line) = callframe.annotations<file line>;

The Perl 6 ecosystem has a module P5defined which exports an undef function that mimics the original Perl 5 behaviour as much as possible.

Add a note here about Type-based undefined values.

Still available. Usable as a method: "filename".IO.unlink

The zero argument (implicit $_) version of unlink is not available in Perl 6.

unpack

Available in Perl 6 when use experimental :pack has been specified in the scope where unpack needs to be called. The template options are currently more restricted than they are in Perl 5. The current documented list can be found at unpack.

The Perl 6 ecosystem has a module P5pack which exports an unpack function that mimics the original Perl 5 behaviour as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.

unshift

Works as in Perl 5, as well as being available as a method: @a.unshift("foo");. Note: the flattening behaviour is different in Perl 6: @b.unshift: @a will unshift @a into @b as a single element. See also the prepend method.

Also note that unshift in Perl 6 returns the array to which was pushed, contrary to Perl 5 where it returns the new number of elements.

The Perl 6 ecosystem has a module P5shift which exports an unshift function that mimics the original Perl 5 behaviour as much as possible.

untie

Not supported in Perl 6, but see tie for the whole story.

The Perl 6 ecosystem has a module P5tie which exports an untie function that mimics the original Perl 5 behaviour as much as possible.

use

In Perl 5, this requires a minimum version of the perl executable in order to run. In Perl 6, this requires a version of the specification, (e.g. 6.c), which can be implemented by various perl6 executables.

utime

No equivalent.

values

Available in Perl 6. Can also be used as a method. values %hash is equivalent to %hash.values.

vec

There is no support for vec() in Perl 6.

S29 says "Should replace vec with declared buffer/array of bit, uint2, uint4, etc." Support for bit, uint2, uint4 has not landed yet. But support for uint8, int8, uint16, int16, uint32, int32, uint64, int64 as well as the system sized uint and int have landed. In scalar forms, as well as in array and shaped array (aka matrix) forms.

wait

[NEEDS FURTHER RESEARCH] Unclear where this has gone. There's a wait method in Supply, and an await method in both Channel and Promise. Which, if any or all, of these is a direct equivalent of Perl 5's wait is unclear.

waitpid

As with wait, the disposition of this is unclear.

wantarray

There is no wantarray in Perl 6; however, there are very easy ways to cover many of the use cases which wantarray filled.

First, since Perl 6 does not need special reference syntax to contain a List or Array in a Scalar, simply returning a list may be all that is needed:

sub listofstuff {
    return 1, 2, 3;
}
my $a = listofstuff();
print $a;                      # prints "123"
print join("<", listofstuff()) # prints "1<2<3"

One of the most common use cases is to provide either an array of lines or elements, or a prettier string than would be produced by simply printing the array. One can mix in a custom .Str method for this purpose:

sub prettylist(*@origlist) {
    @origlist but role {
        method Str { self.join("<") }
    }
}
print prettylist(1, 2, 3);  # prints "1<2<3"
print join(">", prettylist(3, 2, 1)); # prints "3>2>1"

In the above example, the returned list may be lazy, and the .Str method is not called until stringification happens, so no extra work is done to generate something which is not asked for.

Another use case is to create methods which are mutators when called in void context but produce copies during assignment. It is generally considered better form in Perl 6 not to do so, even more so because void context does not exist in Perl 6, with the closest equivalent being sink context, since users can quite easily turn any copy-producing method into a mutator using the .= operator:

my $a = "foo\n";
$a.ords.say; # says "(102 111 111 10)"
$a .= chomp;
$a.ords.say; # says "(102 111 111)"

However if you have your heart set on using the same function name for both operations, you can get most of the way there by mixing in a .sink method, which will be called when the result finds itself in sink context. There are some caveats however, so again, this is not advised:

multi sub increment($b is rw) {
    ($b + 1) does role { method sink { $b++ } }
}
multi sub increment($b) {
    $b + 1
}
my $a = 1;
increment($a);
say $a;                 # says "2"
my $b = increment($a);
say $a, $b;             # says "2 3"
# ...users will just have to be aware that they should not accidentally
# sink a stored value later, though this requires some effort to
# actually do:
sub identity($c is rw) { $c };
$a = 1;
$b = increment($a);
identity($b);
$a.say;                  # says "2"

warn

warn throws a resumable exception. To simply print a message to $*ERR, you would use the note function. For more on exceptions, see Exceptions.

write

Formats are gone from Perl 6, so this no longer works.

y///

This synonym for tr/// is gone. For functionality, see the entry for tr///.

5 Perl 5 to Perl 6 guide - Operators

Operators in Perl 5 to Perl 6: equivalencies and variations

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 operators with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document does not explain the operators in detail. This document is an attempt to guide you from the operators in Perl 5's perlop document to their equivalents in Perl 6. For full documentation on the Perl 6 equivalents, please see the Perl 6 documentation.

Operator Precedence and Associativity

The operator precedence table is somewhat different in Perl 6 than it is in Perl 5, so it will not be detail here. If you need to know the precedence and associativity of a given operator in Perl 6, refer to Operator Precedence.

Terms and List Operators

The things listed in Perl 5's perlop document as unary and list operators in this section tend to be things that can also be thought of as functions, such as print and chdir. As such, you can find information about them in the functions guide. Parentheses are still used for grouping. There is one caveat: in Perl 6, it's the , (comma) that creates lists, not parentheses. So:

my @foo = 1,2,3,4,5;   # no parentheses needed 
 .say for 1,2,3,4,5;    # also no parentheses 
 
 my $scalar = (1);      # *not* a list, as there is no comma 
 my $list   = (1,);     # a List in a scalar container 

The Arrow Operator

As you typically will not be using references in Perl 6, the arrow is probably less useful as a dereferencing operator. If you do need to dereference something, however, the arrow is the dot. It is also the dot for method calls. So, Perl 5's $arrayref->[7] becomes $arrayref.[7] in Perl 6 and, similarly, $user->name becomes $user.name. The => arrow is used for constructing Pairs, see Pair term documentation.

Auto-increment and Auto-decrement

Work as in Perl 5. The one possible caveat is that they function by calling the succ method for ++ and the pred method for --. For builtin numeric types, this is unlikely to do something unusual, but custom types can define their own succ and pred methods, so in those cases, you should probably take note of what ++ and -- will actually do.

Exponentiation

Works as you would expect. The caveat in Perl 5's perlop about ** binding more tightly than unary minus (i. e. "-2**4" evaluates as "-(2**4)" rather than "(-2)**4)") is also true for Perl 6.

Symbolic Unary Operators

As in Perl 5, unary ! and - do logical and arithmetic negation, respectively. ?^ is used for bitwise logical negation, which the documentation indicates is equivalent to !. It may be relevant to note that these coerce their arguments to Bool and Numeric, respectively.

Unary ~ is the string context operator in Perl 6, so use prefix +^ for bitwise integer negation. Assumes two's complement.

+ does have an effect in Perl 6, coercing its argument to the Numeric type.

Unary \ is no more. If you really want to take a "reference" to an existing named variable, you can use item context, like so: $aref = item(@array), or maybe more familiarly by prefixing with a $: $aref = $@array. Please note that you're not really getting a reference, but a scalar container with the referenced object in it.

You can get a "reference" to a named subroutine by using the & sigil: $sref = &foo. Anonymous arrays, hashes, and subs return the underlying object during creation right away: $sref = sub { }.

Binding Operators

=~ and !~ have been replaced by ~~ and !~~, respectively. Those of you who consider smartmatching broken in Perl 5 will be happy to hear that it works much better in Perl 6, as the stronger typing means less guesswork. See the smartmatch documentation for a more extensive explanation of how smartmatch works in Perl 6.

Multiplicative Operators

Binary *, /, and % do multiplication, division, and modulo, respectively, as in Perl 5.

Binary x is slightly different in Perl 6, and has a companion. print '-' x 80; gives you a string of 80 dashes, but for the Perl 5 behavior of @ones = (1) x 80; giving you a list of 80 "1"s, you would use @ones = 1 xx 80;.

Additive Operators

Binary + and - do addition and subtraction, respectively, as you would expect.

As . is the method call operator, so binary ~ acts as the concatenation operator in Perl 6.

Shift Operators

<< and >> have been replaced by +< and +> .

Named Unary Operators

As noted above, you'll find these in the functions guide.

Relational Operators

These all work as in Perl 5.

Equality Operators

== and != both work as in Perl 5.

<=> and cmp have different behavior in Perl 6. <=> does a numeric comparison, but returns Order::Less, Order::Same, or Order::More instead of Perl 5's -1, 0, or 1. To get the Perl 5 behavior (with the change that it returns the Order objects, rather than integers) of cmp, you would use the leg operator.

cmp does either <=> or leg, depending on the existing type of its arguments.

~~ is the smartmatch operator as in Perl 5, but it's also just the match operator in Perl 6, as noted above. For how smartmatching works in Perl 6, see the smartmatch documentation.

Smartmatch Operator

See the smartmatch documentation for a more extensive explanation of how smartmatch works in Perl 6.

Bitwise And

Binary & is +& in Perl 6.

Bitwise Or and Exclusive Or

Bitwise OR has changed from | in Perl 5 to +| in Perl 6. Similarly, bitwise XOR ^ is +^

C-style Logical And

Unchanged.

C-style Logical Or

Unchanged.

Logical Defined-Or

Remains in Perl 6 as //. Returns the first defined operand, or else the last operand. Also, there is a low precedence version, called orelse.

Range Operators

In list context, .. operates as the range operator and should not need to be changed. That said, there are exclusionary range operators that may be useful. These are:

The following example shows the effects of all the above range operators (please note parentheses are used only to allow the method call):

(1..^5).list;  # (1 2 3 4) 
 (1^..5).list;  # (2 3 4 5) 
 (1^..^5).list; # (2 3 4) 
 (^5).list;     # (0 1 2 3 4) 

In Perl 5, in scalar context, the operators .. and ... work as flip-flop operators, even if they are little-known and probably less used. Those operators have been replaced in Perl 6 by ff and fff respectively.

Conditional Operator

The conditional operator ? : has been replaced by ?? !!:

$x = $ok  ? $yes  : $no;  # Perl 5 
$x = $ok ?? $yes !! $no;  # Perl 6 

Assignment Operators

Although not fully documented, S03 indicates that the mathematical and logical assignment operators should work as you would expect. The one noticeable change is that .= calls a mutating method on the object on the left (which can also be a type-object). This allows for the following useful idiom:

class LongClassName { 
     has $.frobnicate; 
 } 
 my LongClassName $bar .= new( frobnicate => 42 ); # no need to repeat class name 

This ensures that $bar will only be able to contain a LongClassName object, as well not having to repeat (and possibly misspell) the class name.

~= is the string concatenation assignment, as you might expect with the changes in . and ~. Also, the bitwise assignment operators are likely not separated into numeric and string versions (&=, etc., vs. &.=, etc.), as that feature is currently experimental in Perl 5 itself - although, again, this is not specifically documented.

Comma Operator

The comma operator works mostly as expected, but technically it creates Lists) or separates arguments in function calls. Also, there is a : variant that turns function calls into method calls - see this page.

The => operator works similarly to the Perl 5 "fat comma" behavior in that it allows an unquoted identifier on its left side, but in Perl 6 constructs Pair objects, rather than just functioning as a separator. If you are trying to just literally translate a line of Perl 5 code to Perl 6, it should behave as expected.

List Operators (Rightward)

Like the Named Unary Operators, you'll find these discussed under Functions.

Logical Not

The lower precedence version of !. As with !, coerces its argument to Bool.

Logical And

Lower precedence version of && as in Perl 5.

Logical or and Exclusive Or

or is the low precedence version of ||, and xor is the low precedence version of ^^.

Additionally, there is a low precedence version of //, called orelse.

Quote and Quote-like Operators

For all the gory details on quoting constructs, see quoting.

There is a quoting operator that allows absolute literal strings: Q or 「…」, although the latter might be difficult to find on your keyboard, depending on your keyboard... Backslash escapes do not apply in Q quoted strings. E. g. Q{This is still a closing curly brace → \} renders "This is still a closing curly brace → \".

q does what you expect, allowing backslash escapes. E. g. q{This is not a closing curly brace → \}, but this is → } returning "This is not a closing curly brace → }, but this is →". As in Perl 5, you can get this behavior with single quotes.

qq allows interpolation of variables. However, by default, only scalar variables are interpolated. To get other variables to interpolate, you need to put square brackets after them (the so-called zen-slice) to get them to interpolate. E.g. @a = <1 2 3>; say qq/@a[] example@example.com/; results in "1 2 3 example@example.com". Hashes interpolate in the same manner: %a = 1 => 2, 3 => 4;say "%a{}"; results in a space separating the pairs and tabs separating the key from the value in each pair (because that's the standard stringification of Pairs, and a hash acts as list of Pairs when stringified). You can also interpolate Perl 6 code in strings using curly braces. For all the details, see Interpolation.

qw works as in Perl 5, and can also be rendered as <...> . E. g. qw/a b c/ is equivalent to <a b c> .

There is also a version of qw that interpolates, which is qqw. So my $a = 42;say qqw/$a b c/; gives you "42 b c".

Shell quoting is available through qx, but you should note that backticks do not do shell quoting as in Perl 5, and Perl variables are not interpolated in qx strings. If you need to interpolate Perl variables in a shell command string, you can use qqx instead.

The qr operator is gone from Perl 6.

tr/// works similarly to how it does in Perl 5. The one caveat is that ranges are specified differently. Instead of using a range "a-z", you would use "a..z", i. e. with Perl's range operator. tr/// has a method version, which is better documented, called .trans. .trans uses a list of pairs, as follows: $x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] => ['D'..'Q'], ['r'..'z'] => ['R'..'Z']); A much more extensive description of the uses of .trans can be found at https://design.perl6.org/S05.html#Transliteration. The y/// equivalent has been done away with.

Heredocs are specified differently in Perl 6. You use :to with your quoting operator, e. g. q:to/END/; would start a heredoc ending with "END". Similarly, you get escaping and interpolation based on your quoting operator, i. e. literals with Q, backslash escapes with q, and interpolation with qq.

I/O Operators

The full details on Input/Output in Perl 6 can be found at io.

As <...> is the quote-words construct in Perl 6, <> is not used for reading lines from a file. You can do that by either making an IO object from a file name or using an open filehandle and then, in either case, calling .lines on it. I. e. either my @a = "filename".IO.lines; or my $fh = open "filename", :r;my @a = $fh.lines; (In the latter case, we are using :r to specifically open the file for reading). To do this in an iterative manner, you can use a for loop this way:

for 'huge-csv'.IO.lines -> $line { 
     # Do something with $line 
 } 

Note the use of -> there. That's part of the Block syntax, and in Perl 6 is needed for if, for, while, etc.

If you want to slurp the entire file into a scalar, you would - surprise! - use the .slurp method. For instance

my $x = "filename".IO.slurp; 
 # ... or ... 
 my $fh = open "filename", :r; 
 my $x = $fh.slurp; 

As noted in the Special Variables guide, the ARGV magic input filehandle has been replaced by $*ARGFILES, and the @ARGV array of command line arguments has been replaced by @*ARGS.

No-ops

1 while foo(); works in the same way as it does in Perl 5, however it generates a warning. In Perl 6 the idiom is now written as Nil while foo(); instead.

Bitwise String Operators

Documented individually above, but to summarize...

Bitwise integer negation is prefix +^. Bitwise boolean negation is ?^.

Bitwise and is +&.

Bitwise integer or is +|. Bitwise integer xor is infix +^. Bitwise boolean or is ?|.

Left shift and right shift are +< and +> .

6 Perl 5 to Perl 6 guide - Syntax

Syntactic differences between Perl 5 and Perl 6

perlsyn - Perl syntax

DESCRIPTION

A (hopefully) comprehensive description of the differences between Perl 5 and Perl 6 with regards to the syntax elements described in the perlsyn document.

NOTE

I will not be explaining Perl 6 syntax in detail. This document is an attempt to guide you from how things work in Perl 5 to the equivalents in Perl 6. For full documentation on the Perl 6 syntax, please see the Perl 6 documentation.

Free Form

Perl 6 is still largely free form. However, there are a few instances where the presence or lack of whitespace is now significant. For instance, in Perl 5, you can omit a space following a keyword (e. g. while($x < 5) or my($x, $y)). In Perl 6, that space is required, thus while ($x < 5) or my ($x, $y). In Perl 6, however, you can omit the parentheses altogether: while $x < 5 . This holds for if, for, etc.

Oddly, in Perl 5, you can leave spaces between an array or hash and its subscript, and before a postfix operator. So $seen {$_} ++ is valid. No more. That would now have to be %seen{$_}++.

If it makes you feel better, you can use backslashes to "unspace" whitespace, so you can use whitespace where it would otherwise be forbidden.

See Whitespace for details.

Declarations

As noted in the Functions guide, there is no undef in Perl 6. A declared, but uninitialized scalar variable will evaluate to its type. In other words, my $x;say $x; will give you "(Any)". my Int $y;say $y; will give you "(Int)".

Comments

# starts a comment that runs to the end of the line as in Perl 5.

Embedded comments start with a hash character and a backtick (#`), followed by an opening bracketing character, and continue to the matching closing bracketing character. Like so:

if #`( why would I ever write an inline comment here? ) True { 
     say "something stupid"; 
 } 

As in Perl 5, you can use pod directives to create multiline comments, with =begin comment before and =end comment after the comment.

Truth and Falsehood

The one difference between Perl 5 truth and Perl 6 truth is that, unlike Perl 5, Perl 6 treats the string "0" as true. Numeric 0 is still false, and you can use prefix + to coerce string "0" to numeric to get it to be false. Perl 6, additionally has an actual Boolean type, so, in many cases, True and False may be available to you without having to worry about what values count as true and false.

Statement Modifiers

Mostly, statement modifiers still work, with a few exceptions.

First, for loops are exclusively what were known in Perl 5 as foreach loops and for is not used for C-style for loops in Perl 6. To get that behavior, you want loop. loop cannot be used as a statement modifier.

In Perl 6, you cannot use the form do {...} while $x. You will want to replace do in that form with repeat. Similarly for do {...} until $x.

Compound Statements

The big change from Perl 5 is that given is not experimental or disabled by default in Perl 6. For the details on given see this page.

Loop Control

next, last, and redo have not changed from Perl 5 to Perl 6.

continue, however, does not exist in Perl 6. You would use a NEXT block in the body of the loop.

# Perl 5 
 my $str = ''; 
 for (1..5) { 
     next if $_ % 2 == 1; 
     $str .= $_; 
 } 
 continue { 
     $str .= ':' 
 } 
 
# Perl 6 
 my $str = ''; 
 for 1..5 { 
     next if $_ % 2 == 1; 
     $str ~= $_; 
     NEXT { 
         $str ~= ':' 
     } 
 } 

For Loops

As noted above, C-style for loops are not called for loops in Perl 6. They are just loop loops. To write an infinite loop, you do not need to use the C idiom of loop (;;) {...}, but may just omit the spec completely: loop {...}

Foreach Loops

In Perl 5, for, in addition to being used for C-style for loops, is a synonym for foreach. In Perl 6, for is just used for foreach style loops.

Switch Statements

Perl 6 has actual switch statements, provided by given with the individual cases handled by when and default. The basic syntax is:

given EXPR { 
     when EXPR { ... } 
     when EXPR { ... } 
     default { ... } 
 } 

The full details can be found here.

Goto

goto is currently not implemented (yet). Labels are implemented, and can be used as a target for next, last and redo:

FOO:                         # Labels end with colons, like in Perl 5 
 for ^10 { 
     say "outer for before"; 
     for ^10 { 
         say "inner for"; 
         last FOO; 
     } 
     say "outer for after";   # Will not show because of the "last" 
 } 
 # outer for before 
 # inner for 

For what is planned for goto, see https://design.perl6.org/S04.html#The_goto_statement.

The Ellipsis Statement

... (along with !!! and ???) are used to create stub declarations. This is a bit more complicated than the use of ... in Perl 5, so you'll probably want to look at https://design.perl6.org/S06.html#Stub_declarations for the gory details. That said, there doesn't seem to be an obvious reason why it shouldn't still fulfill the role it did in Perl 5, despite its role being expanded in Perl 6.

PODs: Embedded Documentation

Pod has changed between Perl 5 and Perl 6. Probably the biggest difference is that you need to enclose your pod between =begin pod and =end pod directives. There are a few tweaks here and there as well. For instance, as I have discovered while writing these documents, the vertical bar ("|") is significant in X<> codes, and it's not clear how to get a literal "|" into them. Your best bet may be to use the Perl 6 interpreter to check your pod. You can do this by using the --doc switch. E. g. perl6 --doc Whatever.pod. This will output any problems to standard error. (Depending on how/where you've installed perl6, you may need to specify the location of Pod::To::Text.) Details on Perl 6 style pod is at https://design.perl6.org/S26.html.

7 Perl 5 to Perl 6 guide - Special Variables

A comparison of special variables in Perl 5 and Perl 6

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 Special Variables with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document is an attempt to guide the reader from the Special Variables in Perl 5 to their equivalents in Perl 6. For full documentation on the Perl 6 Special Variables, please see the Perl 6 documentation for each of them.

SPECIAL VARIABLES

General Variables

Thankfully, $_ is the general default variable as in Perl 5. The main difference in Perl 6 is that you can now call methods on it. For instance, Perl 5's say $_ can be rendered in Perl 6 as $_.say. Furthermore, as it is the default variable, you don't even need to use the variable name. The previous example can also be achieved by using .say.

As Perl 6 now has function signatures, your arguments can go there, rather than depending on @_ for them. In fact, if you use a function signature, use of @_ will spit at you telling it cannot override an existing signature.

If, however, you do not use a function signature, @_ will contain the arguments you pass to the function as it did in Perl 5. Again, as with $_, you can call methods on it. Unlike $_ you cannot assume @_ as the default variable for those methods to operate on (i. e. @_.shift works, .shift does not).

Currently, there is no equivalent of the List Separator variable in Perl 6. Design document S28 says there isn't one, so you probably don't want to hold your breath.

$$ is replaced in Perl 6 by $*PID

You can access the program name in Perl 6 via $*PROGRAM-NAME.

Note: $0 in Perl 6 is the variable holding the first captured value from a regexp match (i. e. capture variables now start from $0 rather than $1).

In Perl 6 the group information is handled by $*GROUP, which holds an object of type IntStr and therefore can be used either within a string or a numeric context. The group id is therefore obtained via +$*GROUP, while the group name via ~$*GROUP.

The effective group id does not appear to be currently provided by Perl 6.

In Perl 6 the user information is handled by $*USER, which holds an object of type IntStr and therefore can be used either within a string or a numeric context (this is similar to how the group information is handled by the $*GROUP object). The user id is therefore obtained via +$*USER, while the username via ~$*USER.

The effective user id does not appear to be currently provided by Perl 6.

The subscript separator variable is not included in Perl 6. Frankly, if your Perl 5 code is using this, it's almost certainly really, really old.

$a and $b have no special meaning in Perl 6. sort() does not use them for anything special. They're just regular old variables.

This feature has been extended by having blocks with placeholder parameters which are more versatile. Placeholder variables are created with the ^ twigil (e. g. $^z. They can be used in a bare block or in a subroutine without an explicit parameter list. The arguments to the block are assigned to the placeholder variables in their Unicode order. I. e. even if the variables appear in the block in the order ($^q, $^z, $^a), they will be assigned in the order ($^a, $^q, $^z). Ergo:

sort { $^a cmp $^z }, 1, 5, 6, 4, 2, 3; 
 # OUTPUT: «(1 2 3 4 5 6)␤» 
 sort { $^g cmp $^a }, 1, 5, 6, 4, 2, 3; 
 # OUTPUT: «(6 5 4 3 2 1)␤» 
 for 1..9 { say $^c, $^a, $^b; last } 
 # OUTPUT: «312␤» 

For more on placeholder variables, see this page

%ENV has been replaced by %*ENV in Perl 6. Note that the keys of this hash may not be exactly the same between Perl 5 and Perl 6. For example, OLDPWD is missing from Perl 6's %ENV.

The running version of Perl 6 is kept by $*PERL special variable, that is an object. The running version is retrieved via $*PERL.version, which returns something like v6.c; the full stringified version of the Perl interpreter is obtained via ~$*PERL, which returns something like Perl 6 (6.c).

Although the design documents (S28) indicate that this will likely become $*SYS_FD_MAX, this has not yet been implemented.

[NEEDS FURTHER RESEARCH] A bit confusing at this point. Design doc S28 indicates that @F in Perl 5 is replaced by @_ in Perl 6, but it's unclear just how that works. On the other hand, it's currently something of a moot point, as the Perl 5 to Perl 6 Translation doc indicates that the -a and -F command-line switches are not yet implemented in rakudo.

No longer exists in Perl 6. Please use "use lib" to manipulate the module repositories to be searched. The closest thing to @INC is really $*REPO. But that works completely differently from @INC mostly because of the precompilation capabilities of Perl 6.

# Print out a list of compunit repositories
.say for $*REPO.repo-chain;

No longer exists in Perl 6. Because each Repository is responsible for remembering which modules have been loaded already. You can get a list of all loaded modules (compilation units) like so:

use Test; 
 use MyModule; 
 say flat $*REPO.repo-chain.map(*.loaded); #-> (MyModule Test) 

S28 suggests $*INPLACE_EDIT, but it does not yet exist.

S28 suggests $*EMERGENCY_MEMORY, but it does not yet exist.

This is somewhat unclear. It probably depends on what you mean by "the name of the operating system" as design document S28 has three different suggestions, all of which give different answers.

There are currently three main objects containing information about the "running environment":

All the above objects have methods in common:

As a short example, the following piece of code prints information about all the above components:

for $*KERNEL, $*DISTRO, $*VM -> $what { 
     say $what.^name; 
     say 'version '  ~ $what.version 
         ~ ' named ' ~ $what.name 
         ~ ' by '    ~ $what.auth; 
 } 
 
 # Kernel 
 # version 4.10.0.42.generic named linux by unknown 
 # Distro 
 # version 17.04.Zesty.Zapus named ubuntu by https://www.ubuntu.com/ 
 # VM 
 # version 2017.11 named moar by The MoarVM Team 

The Str method on all of the above produces the short version of the information, at the current time the name.

All the objects have other methods that can be useful when trying to identify the exact running instance, for more information use <.^methods> to introspect all the above.

No equivalent variable. To have your code executed on the reception of a signal, you can call the signal subroutine, which returns a Supply that can be tapped.

$SIG{"INT"} = sub { say "bye"; exit } 
signal(SIGINT).tap: { say "bye"; exit }; loop {} 

Or, if you have a generic code that want to know which signal it got:

signal(SIGINT).tap: -> $signal { say "bye with $signal"; exit }; loop {} 

A more idiomatic way of using signals in an event driven situation:

react { 
     whenever signal(SIGINT) { 
         say "goodbye"; 
         done 
     } 
 } 

Replaced in Perl 6 by $*INIT-INSTANT. Unlike in Perl 5, this is not in seconds since epoch, but an Instant object, which is measured in atomic seconds, with fractions.

As with $] this has been replaced with $*PERL.version.

There is no analog to this in Perl 6.

This has been replaced by $*EXECUTABLE-NAME. Note that there is also $*EXECUTABLE, which is an IO object in Perl 6.

Performance issues

As shown below, $`, $&, and $' are gone from Perl 6, primarily replaced by variations on $/ and, with their elimination, the associated performance issues in Perl 5 do not apply.

These existing variables do the same thing in Perl 6 as they do in Perl 5, except that they now start at $0 rather than $1. Furthermore, they are synonyms for indexed items in the match variable $/. I. e. $0 is equivalent to $/[0], $1 is equivalent to $/[1], etc.

$/ now contains the match object, so the Perl 5 behavior of $& can be obtained by stringifying it, i. e. ~$/.

Please note that while $/.Str should also work, ~$/ is currently the more common idiom.

Since the former performance issues are done away with, this variable is not of use in Perl 6.

Replaced by $/.prematch.

Since the former performance issues are done away with, this variable is not of use in Perl 6.

Replaced by $/.postmatch.

Since the former performance issues are done away with, this variable is not of use in Perl 6.

Does not exist in Perl 6, but you can get the same information using $/[*- 1].Str ($/[*-1] would be the match object, not the actual string).

If you want to understand why that works, you can look at these documents:

...and possibly

...though the design documents are not always up to date.

S28 suggests $*MOST_RECENT_CAPTURED_MATCH, but there does not seem to be any implemented variable that matches $^N.

As with most regular expression related variables, this functionality is, at least in part, moved to the $/ variable in Perl 6. Or, in this case, the numbered variables that alias to the indexes of it. The offset is found by using the .to method. I. e. the first offset is $/[0].to, which is synonymous with $0.to. The value Perl 5 provides as $+[0] is provided by $/.to.

Once again, we move over to $/. The former $+{$match} is $/{$match}.

Similarly to @+ being replaced by using the .to method, @- is replaced by using the .from method on $/ and its variations. The first offset is $/[0].from or the equivalent $0.from. Perl 5's $- [0] is $/.from.

Much like %+, a use of %-{$match} would be replaced with $/{$match}.

No equivalent.

No equivalent.

No equivalent.

The name of the current file when reading lines can be obtained through $*ARGFILES.path.

@*ARGS contains the command line arguments.

This has been replaced by $*ARGFILES.

As the -i command line switch has not yet been implemented, there is not yet an equivalent of ARGVOUT.

Currently no obvious equivalent.

No direct replacement exists.

When iterating using lines method from IO::Path or IO::Handle types, you can call the .kv method on it to get an interleaved list of indexes and values (then iterate by 2 each loop):

for "foo".IO.lines.kv -> $n, $line { 
     say "{$n + 1}: $line" 
 } 
 # OUTPUT: 
 # 1: a 
 # 2: b 
 # 3: c 
 # 4: d 

For IO::CatHandle types (of which $*ARGFILES is one), you can use on-switch hook to reset line number on handle switch, and increment it manually. See also IO::CatHandle::AutoLines and LN modules that simplify this operation.

This is accessed through the .nl-in method on the filehandle. E. g. $*IN.nl-in.

This is accessed through the .nl-out method on the filehandle. E. g. $*OUT.nl-out.

No global alternative available. TTY handles are unbuffered by default, for others, set out-buffer to zero or use :!out-buffer with open on a specific IO::Handle.

Not implemented in Perl 6.

There are no built-in formats in Perl 6.

Error Variables

Because of how error variables have changed in Perl 6, they will not be detailed here individually.

To quote the Perl 6 docs, "$! is the error variable." That's it. All the error variables appear to have been eaten by $!. As with the rest of Perl 6, it's an object that will return various things depending on the type of error or exception.

In particular, when dealing with exceptions the $! provides information about the thrown exception, assuming the program has not halted:

try { 
     fail "Boooh"; 
     CATCH { 
         # within the catch block 
         # the exception is placed into $_ 
         say 'within the catch:'; 
         say $_.^name ~ ' : ' ~ $_.message; 
         $_.resume; # do not abort 
     } 
 } 
 
 # outside the catch block the exception is placed 
 # into $! 
 say 'outside the catch:'; 
 say $!.^name ~ ' : ' ~ $!.message; 

and the above code produces the following output

within the catch: 
 X::AdHoc : Boooh 
 outside the catch: 
 X::AdHoc : Boooh 

therefore, as stated before, the $! variable holds the exception object.

Currently no equivalents for either of these variables.

Although deprecated in Perl 5, this may have some sort of equivalent in $?ENC, but this is far from clear.

No Perl 6 equivalent.

There may or may not be equivalents of these in Perl 6, but they're internal and you shouldn't be messing with them in the first place - certainly not if your understanding of Perl 6 requires you to read this document...

The chance of the Perl 6 debugger resembling the Perl 5 debugger is slim at best, and at this point there does not seem to be an equivalent of this variable.

S28 claims this variable is "pending". Not currently in Perl 6.

These Unicode-related variables do not appear to exist in Perl 6, but - maybe? - could have analogs in $?ENC somewhere. This, however, is totally unconfirmed.

Deprecated and removed variables

It should go without saying that, as these have been removed from Perl 5 already, there should be no need to tell you how to use them in Perl 6.

8 About the docs

Meta-documentation

This document collection represents the on-going effort to document the Perl 6 programming language with the goals of being: comprehensive; easy to use; easy to navigate; and useful to both newcomers and experienced Perl 6 programmers.

An HTML version of the documentation is located online at https://docs.perl6.org.

The official source for this documentation is located at perl6/doc on GitHub.

This particular document is a quick overview of the process described in more detail in CONTRIBUTING on GitHub. This document also provides a short introduction to writing Perl 6 Pod files, which can be rendered into HTML and other formats.

Structure

All of the documentation is written in Perl 6 Pod and kept in the doc/ directory, and the doc/Language/ and doc/Type/ sub-directories. These files are processed as collections of definitions or "documentables", which are then post-processed and linked together.

Generating HTML from Pod

To generate HTML from the Pod files, you'll need:

To generate the documentation into the html/ folder, run:

perl6 htmlify.p6 

To host the documentation from a web server, have Perl 5 and Mojolicious::Lite installed, then run:

perl app.pl daemon 

Contributing

The documentation is written in Perl 6 Pod.

For a quick introduction to Perl 6 Pod, see Perl 6 Pod.

For full details about the Perl 6 Pod specification, see Synopsis 26, Documentation.

Adding definitions

Documentables can be defined using an =headN Pod directive, where N is greater than zero (e.g., =head1, =head2, …).

All of the paragraphs and blocks following that directive, up until the next directive of the same level, will be considered part of the documentable. So, in:

=head2  My Definition 
 
 Some paragraphs, followed by some code: 
 
     my Code $examples = "amazing"; 
 
 Mind === blown. 
 
 =head3 Minor details about  My Definition 
 
 It's fantastic. 
 
 =head2 And now, for something completely different 
 
 … 
 

The documentable My Definition extends down to the =head2 And now….

Documentables may contain other documentables. Class documentables, for example, often contain the methods the class implements.

Definitions must be in one of the following forms to be recognized as the start of a documentable named, say, þ. First the code in the document source:

=item X<C<How to use the þ infix> | infix,þ> (This a special case, which 
 is always considered a definition) 
 
 =item C<The þ Infix> 
 
 =item B<The C<þ> Infix> 
 
 =item C<Infix þ> 
 
 =item B<Infix C<þ>> 
 
 =item C<trait is cached> (A special case for the L<trait|/language/functions#Traits> documentables) 
 

Then the results on the rendered page:

These items should now be searchable by using the search field in the HTML docs.

You can add emphasis with bold ( B<> ) or italicized ( I<> ), with or without code formatting ( C<> ). Due to current parser limitations, special steps have to be taken to use X<> with other formatting codes; for example:

=item X<B<foo>|foo> a fancy subroutine 

renders like this

Notice that text after a pipe ('|') has no formatting. Also note that C<> preserves spaces and treats text as verbatim.

9 Classes and Objects

A tutorial about creating and using classes in Perl 6

Perl 6 has a rich built-in syntax for defining and using classes.

A default constructor allows the setting of attributes for the created object:

class Point { 
     has Int $.x; 
     has Int $.y; 
 } 
 
 class Rectangle { 
     has Point $.lower; 
     has Point $.upper; 
 
     method area() returns Int { 
         ($!upper.x - $!lower.x) * ( $!upper.y - $!lower.y); 
     } 
 } 
 
 # Create a new Rectangle from two Points 
 my $r = Rectangle.new(lower => Point.new(x => 0, y => 0), 
                       upper => Point.new(x => 10, y => 10)); 
 
 say $r.area(); # OUTPUT: «100␤» 

In the two classes, the default constructor is being used. This constructor will use named parameters in its invocation: Point.new(x => 0, y => 0).

You can also provide your own construction and BUILD implementation. The following, more elaborate example shows how a dependency handler might look in Perl 6. It showcases custom constructors, private and public attributes, Submethods, methods and various aspects of signatures. It's not a lot of code, and yet the result is interesting and useful.

class Task { 
     has      &!callback; 
     has Task @!dependencies; 
     has Bool $.done; 
 
     # Normally doesn't need to be written 
     method new(&callback, *@dependencies) { 
         return self.bless(:&callback, :@dependencies); 
     } 
 
     # BUILD is the equivalent of a constructor in other languages 
     submethod BUILD(:&!callback, :@!dependencies) { } 
 
     method add-dependency(Task $dependency) { 
         push @!dependencies, $dependency; 
     } 
 
     method perform() { 
         unless $!done { 
             .perform() for @!dependencies; 
             &!callback(); 
             $!done = True; 
         } 
     } 
 } 
 
 my $eat = 
     Task.new({ say 'eating dinner. NOM!' }, 
         Task.new({ say 'making dinner' }, 
             Task.new({ say 'buying food' }, 
                 Task.new({ say 'making some money' }), 
                 Task.new({ say 'going to the store' }) 
             ), 
             Task.new({ say 'cleaning kitchen' }) 
         ) 
     ); 
 
 $eat.perform(); 

In this case, BUILD is needed since we have overridden the default new. bless is eventually (after calling BUILDALL) invoking it with the two named arguments that correspond to the two properties without a default value. With its signature, BUILD converts the two positionals to the two attributes, &!callback and @!dependencies, and returns the object (or turns it in to the next phase, TWEAK, if available).

Declaring new as a method and not a multi method prevents us from using the default constructor; tis implicit constructor uses the attributes as named parameters. That is one of the reasons why using new is discouraged. If you need to declare it anyway, use multi method new if you do not want to disable the default constructors.

TWEAK is the last submethod to be called, and it has got the advantage of having the object properties available without needing to use the meta object protocol. It can be used, for instance, to assign values to instance variables based on the values of other attributes or instance variables:

class Str-with-ID is Str { 
     my $.counter = 0; 
     has Str $.string; 
     has Int $.ID; 
 
     method TWEAK() { 
         $!ID = $.counter++; 
     } 
 } 
 
 say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0» 
 say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1» 

In this case, we need to compute $.ID from the value of a counter that is a class variable, $.counter, thus we simply assign a value to it and increment the counter at the same time. Please check also this section on TWEAK in the OO document for the mechanics of object construction.

Starting with class

Perl 6, like many other languages, uses the class keyword to define a class. The block that follows may contain arbitrary code, just as with any other block, but classes commonly contain state and behavior declarations. The example code includes attributes (state), introduced through the has keyword, and behaviors, introduced through the method keyword.

Declaring a class creates a new type object which, by default, is installed into the current package (just like a variable declared with our scope). This type object is an "empty instance" of the class. For example, types such as Int and Str refer to the type object of one of the Perl 6 built-in classes. The example above uses the class name Task so that other code can refer to it later, such as to create class instances by calling the new method.

You can use .DEFINITE method to find out if what you have is an instance or a type object:

say Int.DEFINITE; # OUTPUT: «False␤» (type object)
say 426.DEFINITE; # OUTPUT: «True␤»  (instance)

class Foo {};
say Foo.DEFINITE;     # OUTPUT: «False␤» (type object)
say Foo.new.DEFINITE; # OUTPUT: «True␤»  (instance)

You can also use type smileys to only accept instances or type objects:

multi foo (Int:U) { "It's a type object!" }
multi foo (Int:D) { "It's an instance!"   }
say foo Int; # OUTPUT: «It's a type object!␤»
say foo 42;  # OUTPUT: «It's an instance!␤»

State

The first three lines inside the class block all declare attributes (called fields or instance storage in other languages). Just as a my variable cannot be accessed from outside its declared scope, attributes are not accessible outside of the class. This encapsulation is one of the key principles of object oriented design.

The first declaration specifies instance storage for a callback – a bit of code to invoke in order to perform the task that an object represents:

has &!callback; 

The & sigil indicates that this attribute represents something invocable. The ! character is a twigil, or secondary sigil. A twigil forms part of the name of the variable. In this case, the ! twigil emphasizes that this attribute is private to the class.

The second declaration also uses the private twigil:

has Task @!dependencies; 

However, this attribute represents an array of items, so it requires the @ sigil. These items each specify a task that must be completed before the present one can complete. Furthermore, the type declaration on this attribute indicates that the array may only hold instances of the Task class (or some subclass of it).

The third attribute represents the state of completion of a task:

has Bool $.done; 

This scalar attribute (with the $ sigil) has a type of Bool. Instead of the ! twigil, the . twigil is used. While Perl 6 does enforce encapsulation on attributes, it also saves you from writing accessor methods. Replacing the ! with a . both declares the attribute $!done and an accessor method named done. It's as if you had written:

has Bool $!done;
method done() { return $!done }

Note that this is not like declaring a public attribute, as some languages allow; you really get both a private attribute and a method, without having to write the method by hand. You are free instead to write your own accessor method, if at some future point you need to do something more complex than return the value.

Note that using the . twigil has created a method that will provide read-only access to the attribute. If instead the users of this object should be able to reset a task's completion state (perhaps to perform it again), you can change the attribute declaration:

has Bool $.done is rw;

The is rw trait causes the generated accessor method to return something external code can modify to change the value of the attribute.

You can also supply default values to attributes (which works equally for those with and without accessors):

has Bool $.done = False;

The assignment is carried out at object build time. The right-hand side is evaluated at that time, and can even reference earlier attributes:

has Task @!dependencies; 
 has $.ready = not @!dependencies; 

A class declaration can also include class variables, which are variables that are shared by all instances, and can be used for things like counting the number of instantiations or any other shared state. Class variables use the same syntax as the rest of the attributes, but are declared as my or our, depending on the scope; the second type of variables will be used across the class hierarchy.

class Str-with-ID is Str { 
     my $.counter = 0; 
     has Str $.string; 
     has Int $.ID; 
 
     method new( Str $string ) { 
         self.bless( :$string, ID => $.counter++ ) 
     } 
 } 
 
 say Str-with-ID.new('First').ID;  # OUTPUT: «0» 
 say Str-with-ID.new('Second').ID; # OUTPUT: «1» 

In this case, using new might be the easiest way to initialize the $.ID field and increment the value of the counter at the same time. new, through bless, will invoke the default BUILD, assigning the values to their properties correctly. You can obtain the same effect using TWEAK, which is considered a more p6y way. Please check the section on submethods for an alternative example on how to do this.

Static fields?

Perl 6 has no static keyword. Nevertheless, any class may declare anything that a module can, so making a scoped variable sounds like good idea.

class Singleton { 
     my Singleton $instance; 
     method new {!!!} 
     submethod instance { 
         $instance = Singleton.bless unless $instance; 
         $instance; 
     } 
 } 
 

Class attributes defined by my or our may also be initialized when being declared, however we are implementing the Singleton pattern here and the object must be created during its first use. It is not 100% possible to predict the moment when attribute initialization will be executed, because it can take place during compilation, runtime or both, especially when importing the class using the use keyword.

class HaveStaticAttr { 
       my Foo $.foo = some_complicated_subroutine; 
 } 

Class attributes may also be declared with a secondary sigil – in a similar manner to object attributes – that will generate read-only accessors if the attribute is to be public.

Methods

While attributes give objects state, methods give objects behaviors. Let's ignore the new method temporarily; it's a special type of method. Consider the second method, add-dependency, which adds a new task to a task's dependency list.

method add-dependency(Task $dependency) { 
     push @!dependencies, $dependency; 
 } 

In many ways, this looks a lot like a sub declaration. However, there are two important differences. First, declaring this routine as a method adds it to the list of methods for the current class, thus any instance of the Task class can call it with the . method call operator. Second, a method places its invocant into the special variable self.

The method itself takes the passed parameter – which must be an instance of the Task class – and pushes it onto the invocant's @!dependencies attribute.

The perform method contains the main logic of the dependency handler:

method perform() { 
     unless $!done { 
         .perform() for @!dependencies; 
         &!callback(); 
         $!done = True; 
     } 
 } 

It takes no parameters, working instead with the object's attributes. First, it checks if the task has already completed by checking the $!done attribute. If so, there's nothing to do.

Otherwise, the method performs all of the task's dependencies, using the for construct to iterate over all of the items in the @!dependencies attribute. This iteration places each item – each a Task object – into the topic variable, $_. Using the . method call operator without specifying an explicit invocant uses the current topic as the invocant. Thus the iteration construct calls the .perform() method on every Task object in the @!dependencies attribute of the current invocant.

After all of the dependencies have completed, it's time to perform the current Task's task by invoking the &!callback attribute directly; this is the purpose of the parentheses. Finally, the method sets the $!done attribute to True, so that subsequent invocations of perform on this object (if this Task is a dependency of another Task, for example) will not repeat the task.

Private Methods

Just like attributes, methods can also be private. Private methods are declared with a prefixed exclamation mark. They are called with self! followed by the method's name. To call a private method of another class the calling class has to be trusted by the called class. A trust relationship is declared with trusts and the class to be trusted must already be declared. Calling a private method of another class requires an instance of that class and the fully qualified name of the method. Trust also allows access to private attributes.

class B {...}

class C {
    trusts B;
    has $!hidden = 'invisible';
    method !not-yours () { say 'hidden' }
    method yours-to-use () {
        say $!hidden;
        self!not-yours();
    }
}

class B {
    method i-am-trusted () {
        my C $c.=new;
        $c!C::not-yours();
    }
}

C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C
B.new.i-am-trusted();

Trust relationships are not subject to inheritance. To trust the global namespace, the pseudo package GLOBAL can be used.

Constructors

Perl 6 is rather more liberal than many languages in the area of constructors. A constructor is anything that returns an instance of the class. Furthermore, constructors are ordinary methods. You inherit a default constructor named new from the base class Mu, but you are free to override new, as this example does:

method new(&callback, *@dependencies) {
    return self.bless(:&callback, :@dependencies);
}

The biggest difference between constructors in Perl 6 and constructors in languages such as C# and Java is that rather than setting up state on a somehow already magically created object, Perl 6 constructors create the object themselves. The easiest way to do this is by calling the bless method, also inherited from Mu. The bless method expects a set of named parameters to provide the initial values for each attribute.

The example's constructor turns positional arguments into named arguments, so that the class can provide a nice constructor for its users. The first parameter is the callback (the thing which will execute the task). The rest of the parameters are dependent Task instances. The constructor captures these into the @dependencies slurpy array and passes them as named parameters to bless (note that :&callback uses the name of the variable – minus the sigil – as the name of the parameter).

Private attributes really are private. This means that bless is not allowed to bind things to &!callback and @!dependencies directly. To do this, we override the BUILD submethod, which is called on the brand new object by bless:

submethod BUILD(:&!callback, :@!dependencies) { } 

Since BUILD runs in the context of the newly created Task object, it is allowed to manipulate those private attributes. The trick here is that the private attributes (&!callback and @!dependencies) are being used as the bind targets for BUILD's parameters. Zero-boilerplate initialization! See objects for more information.

The BUILD method is responsible for initializing all attributes and must also handle default values:

has &!callback; 
 has @!dependencies; 
 has Bool ($.done, $.ready); 
 submethod BUILD( 
         :&!callback, 
         :@!dependencies, 
         :$!done = False, 
         :$!ready = not @!dependencies 
     ) { } 

See Object Construction for more options to influence object construction and attribute initialization.

Consuming our class

After creating a class, you can create instances of the class. Declaring a custom constructor provides a simple way of declaring tasks along with their dependencies. To create a single task with no dependencies, write:

my $eat = Task.new({ say 'eating dinner. NOM!' }); 

An earlier section explained that declaring the class Task installed a type object in the namespace. This type object is a kind of "empty instance" of the class, specifically an instance without any state. You can call methods on that instance, as long as they do not try to access any state; new is an example, as it creates a new object rather than modifying or accessing an existing object.

Unfortunately, dinner never magically happens. It has dependent tasks:

my $eat = 
     Task.new({ say 'eating dinner. NOM!' }, 
         Task.new({ say 'making dinner' }, 
             Task.new({ say 'buying food' }, 
                 Task.new({ say 'making some money' }), 
                 Task.new({ say 'going to the store' }) 
             ), 
             Task.new({ say 'cleaning kitchen' }) 
         ) 
     ); 

Notice how the custom constructor and sensible use of whitespace makes task dependencies clear.

Finally, the perform method call recursively calls the perform method on the various other dependencies in order, giving the output:

making some money 
 going to the store 
 buying food 
 cleaning kitchen 
 making dinner 
 eating dinner. NOM! 

Inheritance

Object Oriented Programming provides the concept of inheritance as one of the mechanisms for code reuse. Perl 6 supports the ability for one class to inherit from one or more classes. When a class inherits from another class it informs the method dispatcher to follow the inheritance chain to look for a method to dispatch. This happens both for standard methods defined via the method keyword and for methods generated through other means, such as attribute accessors.

class Employee { 
     has $.salary; 
 } 
 
 class Programmer is Employee { 
     has @.known_languages is rw; 
     has $.favorite_editor; 
 
     method code_to_solve( $problem ) { 
         return "Solving $problem using $.favorite_editor in " 
         ~ $.known_languages[0]; 
     } 
 } 

Now, any object of type Programmer can make use of the methods and accessors defined in the Employee class as though they were from the Programmer class.

my $programmer = Programmer.new( 
     salary => 100_000, 
     known_languages => <Perl5 Perl6 Erlang C++>, 
     favorite_editor => 'vim' 
 ); 
 
 say $programmer.code_to_solve('halting problem'), " will get ", $programmer.salary(), "\$"; 
 #OUTPUT: «Solving halting problem using vim in Perl5 will get 100000$␤» 

Overriding inherited methods

Of course, classes can override methods and attributes defined by parent classes by defining their own. The example below demonstrates the Baker class overriding the Cook's cook method.

class Cook is Employee { 
     has @.utensils  is rw; 
     has @.cookbooks is rw; 
 
     method cook( $food ) { 
         say "Cooking $food"; 
     } 
 
     method clean_utensils { 
         say "Cleaning $_" for @.utensils; 
     } 
 } 
 
 class Baker is Cook { 
     method cook( $confection ) { 
         say "Baking a tasty $confection"; 
     } 
 } 
 
 my $cook = Cook.new( 
     utensils => <spoon ladle knife pan>, 
     cookbooks => 'The Joy of Cooking', 
     salary => 40000); 
 
 $cook.cook( 'pizza' );       # OUTPUT: «Cooking pizza␤» 
 say $cook.utensils.perl;     # OUTPUT: «["spoon", "ladle", "knife", "pan"]␤» 
 say $cook.cookbooks.perl;    # OUTPUT: «["The Joy of Cooking"]␤» 
 say $cook.salary;            # OUTPUT: «40000␤» 
 
 my $baker = Baker.new( 
     utensils => 'self cleaning oven', 
     cookbooks => "The Baker's Apprentice", 
     salary => 50000); 
 
 $baker.cook('brioche');      # OUTPUT: «Baking a tasty brioche␤» 
 say $baker.utensils.perl;    # OUTPUT: «["self cleaning oven"]␤» 
 say $baker.cookbooks.perl;   # OUTPUT: «["The Baker's Apprentice"]␤» 
 say $baker.salary;           # OUTPUT: «50000␤» 

Because the dispatcher will see the cook method on Baker before it moves up to the parent class the Baker's cook method will be called.

To access methods in the inheritance chain use re-dispatch or the MOP.

Multiple inheritance

As mentioned before, a class can inherit from multiple classes. When a class inherits from multiple classes the dispatcher knows to look at both classes when looking up a method to search for. Perl 6 uses the C3 algorithm to linearize multiple inheritance hierarchies, which is better than depth-first search for handling multiple inheritance.

class GeekCook is Programmer is Cook { 
     method new( *%params ) { 
         push( %params<cookbooks>, "Cooking for Geeks" ); 
         return self.bless(|%params); 
     } 
 } 
 
 my $geek = GeekCook.new( 
     books           => 'Learning Perl 6', 
     utensils        => ('stainless steel pot', 'knife', 'calibrated oven'), 
     favorite_editor => 'MacVim', 
     known_languages => <Perl6> 
 ); 
 
 $geek.cook('pizza'); 
 $geek.code_to_solve('P =? NP'); 

Now all the methods made available to the Programmer and the Cook classes are available from the GeekCook class.

While multiple inheritance is a useful concept to know and occasionally use, it is important to understand that there are more useful OOP concepts. When reaching for multiple inheritance it is good practice to consider whether the design wouldn't be better realized by using roles, which are generally safer because they force the class author to explicitly resolve conflicting method names. For more information on roles see Roles.

The also declarator

Classes to be inherited from can be listed in the class declaration body by prefixing the is trait with also. This also works for the role composition trait does.

class GeekCook { 
     also is Programmer; 
     also is Cook; 
     # ... 
 } 
 
 role A {}; 
 role B {}; 
 class C { also does A; also does B } 

Introspection

Introspection is the process of gathering information about some objects in your program, not by reading the source code, but by querying the object (or a controlling object) for some properties, such as its type.

Given an object $o and the class definitions from the previous sections, we can ask it a few questions:

if $o ~~ Employee { say "It's an employee" }; 
 if $o ~~ GeekCook { say "It's a geeky cook" }; 
 say $o.WHAT; 
 say $o.perl; 
 say $o.^methods(:local)».name.join(', '); 
 say $o.^name; 

The output can look like this:

It's an employee 
 (Programmer) 
 Programmer.new(known_languages => ["Perl", "Python", "Pascal"], 
         favorite_editor => "gvim", salary => "too small") 
 code_to_solve, known_languages, favorite_editor 
 Programmer 

The first two tests each smartmatch against a class name. If the object is of that class, or of an inheriting class, it returns true. So the object in question is of class Employee or one that inherits from it, but not GeekCook.

The .WHAT method returns the type object associated with the object $o, which tells us the exact type of $o: in this case Programmer.

$o.perl returns a string that can be executed as Perl code, and reproduces the original object $o. While this does not work perfectly in all cases, it is very useful for debugging simple objects.

For example closures cannot easily be reproduced this way; if you don't know what a closure is don't worry. Also current implementations have problems with dumping cyclic data structures this way, but they are expected to be handled correctly by .perl at some point.
$o.^methods(:local) produces a list of Methods that can be called on $o. The :local named argument limits the returned methods to those defined in the Programmer class and excludes the inherited methods.

The syntax of calling a method with .^ instead of a single dot means that it is actually a method call on its meta class, which is a class managing the properties of the Programmer class – or any other class you are interested in. This meta class enables other ways of introspection too:

say $o.^attributes.join(', '); 
 say $o.^parents.map({ $_.^name }).join(', '); 

Finally $o.^name calls the name method on the meta object, which unsurprisingly returns the class name.

Introspection is very useful for debugging and for learning the language and new libraries. When a function or method returns an object you don't know about, finding its type with .WHAT, seeing a construction recipe for it with .perl, and so on, you'll get a good idea of what its return value is. With .^methods you can learn what you can do with the class.

But there are other applications too: a routine that serializes objects to a bunch of bytes needs to know the attributes of that object, which it can find out via introspection.

Overriding default gist method

Some classes might need its own version of gist, which overrides the terse way it is printed when called to provide a default representation of the class. For instance, exceptions might want to write just the payload and not the full object so that it is clearer what has happened. But you can do that with every class:

class Cook { 
     has @.utensils  is rw; 
     has @.cookbooks is rw; 
 
     method cook( $food ) { 
         return "Cooking $food"; 
     } 
 
     method clean_utensils { 
         return "Cleaning $_" for @.utensils; 
     } 
 
     multi method gist(Cook:U:) { '⚗' ~ self.^name ~ '⚗' } 
     multi method gist(Cook:D:) { '⚗ Cooks with ' ~ @.utensils.join( " ‣ ") ~ ' using ' ~ @.cookbooks.map( "«" ~ * ~ "»").join( " and ") } 
 } 
 
 my $cook = Cook.new( 
     utensils => <spoon ladle knife pan>, 
     cookbooks => ['Cooking for geeks','The French Chef Cookbook']); 
 
 say Cook.gist; # OUTPUT: «⚗Cook⚗» 
 say $cook.gist; # OUTPUT: «⚗ Cooks with spoon ‣ ladle ‣ knife ‣ pan using «Cooking for geeks» and «The French Chef Cookbook»␤» 

Usually you will want to define two methods, one for the class and another for instances; in this case, the class method uses the alembic symbol, and the instance method, defined below, aggregates the data we have on the cook to show it in a narrative way.

10 Community

Information about the people working on and using Perl 6

Overview

"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community's rewrite of Perl and of the community." - Larry Wall

The Perl 6 community

There is a large presence on the #perl6 channel on freenode.net, who are happy to provide support and answer questions. More resources can be found in the perl6.org community page. Camelia, the multi-color butterfly with P 6 in her wings, is the symbol of this diverse and welcoming community. We use extensively the #perl6 IRC channel for communication, questions and simply hanging out. Check out this IRC lingo resource for the abbreviations frequently used there. StackOverflow is also a great resource for asking questions and helping others with their Perl 6 problems and challenges.

Perl 6 Weekly

Elizabeth Mattijsen usually posts in the "Perl 6 Weekly" blog, a summary of Perl 6 posts, tweets, comments and other interesting tidbits. Best single resource to know what is going on in the Perl community now.

Perl 6 Advent calendar

The Perl 6 community publishes every December an Advent Calendar, with Perl 6 tutorials every day until Christmas. Organization and assignment of days is done through the different Perl 6 channels and the Perl6/mu repository. If you want to participate, it starts organization by the end of October, so check out the channels above for that.

11 Concurrency

Concurrency and asynchronous programming

In common with most modern programming languages, Perl 6 is designed to support parallelism, asynchronicity and concurrency. Parallelism is about doing multiple things at once. Asynchronous programming, which is sometimes called event driven or reactive programming, is about supporting changes in the program flow caused by events triggered elsewhere in the program. Finally, concurrency is about the coordination of access and modification of some shared resources.

The aim of the Perl 6 concurrency design is to provide a high-level, composable and consistent interface, regardless of how a virtual machine may implement it for a particular operating system, through layers of facilities as described below.

I'm not quite clear which specific features should be included below hyper-operators, autothreading junctions?

Additionally, certain Perl features may implicitly operate in an asynchronous fashion, so in order to ensure predictable interoperation with these features, user code should, where possible, avoid the lower level concurrency APIs (e.g., Thread and Scheduler) and use the higher-level interfaces.

High-level APIs

Promises

A Promise (also called future in other programming environments) encapsulates the result of a computation that may not have completed or even started at the time the promise is obtained. A Promise starts from a Planned status and can result in either a Kept status, meaning the promise has been successfully completed, or a Broken status meaning that the promise has failed. Usually this is much of the functionality that user code needs to operate in a concurrent or asynchronous manner.

my $p1 = Promise.new; 
 say $p1.status;         # OUTPUT: «Planned␤» 
 $p1.keep('Result'); 
 say $p1.status;         # OUTPUT: «Kept␤» 
 say $p1.result;         # OUTPUT: «Result␤» 
                         # (since it has been kept, a result is available!) 
 
 my $p2 = Promise.new; 
 $p2.break('oh no'); 
 say $p2.status;         # OUTPUT: «Broken␤» 
 say $p2.result;         # dies, because the promise has been broken 
 CATCH { default { say .^name, ': ', .Str } }; 
 # OUTPUT: «X::AdHoc+{X::Promise::Broken}: oh no␤» 

Promises gain much of their power by being composable, for example by chaining, usually by the then method:

my $promise1 = Promise.new();
my $promise2 = $promise1.then(
    -> $v { say $v.result; "Second Result" }
);
$promise1.keep("First Result");
say $promise2.result;   # OUTPUT: «First Result␤Second Result␤»

Here the then method schedules code to be executed when the first Promise is kept or broken, itself returning a new Promise which will be kept with the result of the code when it is executed (or broken if the code fails). keep changes the status of the promise to Kept setting the result to the positional argument. result blocks the current thread of execution until the promise is kept or broken, if it was kept then it will return the result (that is the value passed to keep), otherwise it will throw an exception based on the value passed to break. The latter behaviour is illustrated with:

my $promise1 = Promise.new();
my $promise2 = $promise1.then(-> $v { say "Handled but : "; say $v.result});
$promise1.break("First Result");
try $promise2.result;
say $promise2.cause;        # OUTPUT: «Handled but : ␤First Result␤»

Here the break will cause the code block of the then to throw an exception when it calls the result method on the original promise that was passed as an argument, which will subsequently cause the second promise to be broken, raising an exception in turn when its result is taken. The actual Exception object will then be available from cause. If the promise had not been broken cause would raise a X::Promise::CauseOnlyValidOnBroken exception.

A Promise can also be scheduled to be automatically kept at a future time:

my $promise1 = Promise.in(5);
my $promise2 = $promise1.then(-> $v { say $v.status; 'Second Result' });
say $promise2.result;

The method in creates a new promise and schedules a new task to call keep on it no earlier than the supplied number of seconds, returning the new Promise object.

A very frequent use of promises is to run a piece of code, and keep the promise once it returns successfully, or break it when the code dies. The start method provides a shortcut for that:

my $promise = Promise.start(
    { my $i = 0; for 1 .. 10 { $i += $_ }; $i}
);
say $promise.result;    # OUTPUT: «55␤»

Here the result of the promise returned is the value returned from the code. Similarly if the code fails (and the promise is thus broken), then cause will be the Exception object that was thrown:

my $promise = Promise.start({ die "Broken Promise" });
try $promise.result;
say $promise.cause;

This is considered to be such a commonly required pattern that it is also provided as subroutines:

my $promise = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
    }
    $i
}
my $result = await $promise;
say $result;

await is almost equivalent to calling result on the promise object returned by start but it will also take a list of promises and return the result of each:

my $p1 = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
    }
    $i
};
my $p2 = start {
    my $i = 0;
    for 1 .. 10 {
        $i -= $_
    }
    $i
};
my @result = await $p1, $p2;
say @result;            # OUTPUT: «[55 -55]␤»

In addition to await, two class methods combine several Promise objects into a new promise: allof returns a promise that is kept when all the original promises are kept or broken:

my $promise = Promise.allof(
    Promise.in(2),
    Promise.in(3)
);

await $promise;
say "All done"; # Should be not much more than three seconds later

And anyof returns a new promise that will be kept when any of the original promises is kept or broken:

my $promise = Promise.anyof(
    Promise.in(3),
    Promise.in(8600)
);

await $promise;
say "All done"; # Should be about 3 seconds later

Unlike await however the results of the original kept promises are not available without referring to the original, so these are more useful when the completion or otherwise of the tasks is more important to the consumer than the actual results, or when the results have been collected by other means. You may, for example, want to create a dependent Promise that will examine each of the original promises:

my @promises;
for 1..5 -> $t {
    push @promises, start {
        sleep $t;
        Bool.pick;
    };
}
say await Promise.allof(@promises).then({ so all(@promises>>.result) });

Which will give True if all of the promises were kept with True, False otherwise.

If you are creating a promise that you intend to keep or break yourself then you probably don't want any code that might receive the promise to inadvertently (or otherwise) keep or break the promise before you do. For this purpose there is the method vow, which returns a Vow object which becomes the only mechanism by which the promise can be kept or broken. If an attempt to keep or break the Promise is made directly then the exception X::Promise::Vowed will be thrown, as long as the vow object is kept private, the status of the promise is safe:

sub get_promise {
    my $promise = Promise.new;
    my $vow = $promise.vow;
    Promise.in(10).then({$vow.keep});
    $promise;
}

my $promise = get_promise();

# Will throw an exception
# "Access denied to keep/break this Promise; already vowed"
$promise.keep;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Promise::Vowed: Access denied to keep/break this Promise; already vowed␤»

The methods that return a promise that will be kept or broken automatically such as in or start will do this, so it is not necessary to do it for these.

Supplies

A Supply is an asynchronous data streaming mechanism that can be consumed by one or more consumers simultaneously in a manner similar to "events" in other programming languages and can be seen as enabling "Event Driven" or reactive designs.

At its simplest, a Supply is a message stream that can have multiple subscribers created with the method tap on to which data items can be placed with emit.

The Supply can either be live or on-demand. A live supply is like a TV broadcast: those who tune in don't get previously emitted values. An on-demand broadcast is like Netflix: everyone who starts streaming a movie (taps a supply), always starts it from the beginning (gets all the values), regardless of how many people are watching it right now. Note that no history is kept for on-demand supplies, instead, the supply block is run for each tap of the supply.

A live Supply is created by the Supplier factory, each emitted value is passed to all the active tappers as they are added:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;

$supply.tap( -> $v { say $v });

for 1 .. 10 {
    $supplier.emit($_);
}

Note that the tap is called on a Supply object created by the Supplier and new values are emitted on the Supplier.

An on-demand Supply is created by the supply keyword:

my $supply = supply {
    for 1 .. 10 {
        emit($_);
    }
}
$supply.tap( -> $v { say $v });

In this case the code in the supply block is executed every time the Supply returned by supply is tapped, as demonstrated by:

my $supply = supply {
    for 1 .. 10 {
        emit($_);
    }
}
$supply.tap( -> $v { say "First : $v" });
$supply.tap( -> $v { say "Second : $v" });

The tap method returns a Tap object which can be used to obtain information about the tap and also to turn it off when we are no longer interested in the events:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;

my $tap = $supply.tap( -> $v { say $v });

$supplier.emit("OK");
$tap.close;
$supplier.emit("Won't trigger the tap");

Calling done on the supply object calls the done callback that may be specified for any taps, but does not prevent any further events being emitted to the stream, or taps receiving them.

The method interval returns a new on-demand supply which periodically emits a new event at the specified interval. The data that is emitted is an integer starting at 0 that is incremented for each event. The following code outputs 0 .. 5 :

my $supply = Supply.interval(2);
$supply.tap(-> $v { say $v });
sleep 10;

react and whenever

This could also be written using the react keyword:

react {
    whenever Supply.interval(2) -> $v {
        say $v;
        done() if $v == 4;
    }
}

Here the whenever keyword uses .act to create a tap on the Supply from the provided block. The react block is exited when done() is called in one of the taps. Using last to exit the block would produce an error indicating that it's not really a loop construct.

A second argument can be supplied to interval which specifies a delay in seconds before the first event is fired. Each tap of a supply created by interval has its own sequence starting from 0, as illustrated by the following:

my $supply = Supply.interval(2);
$supply.tap(-> $v { say "First $v" });
sleep 6;
$supply.tap(-> $v { say "Second $v"});
sleep 10;

An on-demand Supply can also be created from a list of values that will be emitted in turn, thus the first on-demand example could be written as:

react {
    whenever Supply.from-list(1..10) -> $v {
        say $v;
    }
}

A live Supply that keeps values until first tapped can be created with Supplier::Preserving.

An existing supply object can be filtered or transformed, using the methods grep and map respectively, to create a new supply in a manner like the similarly named list methods: grep returns a supply such that only those events emitted on the source stream for which the grep condition is true is emitted on the second supply:

my $supplier = Supplier.new;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "Original : $v" });
my $odd_supply = $supply.grep({ $_ % 2 });
$odd_supply.tap(-> $v { say "Odd : $v" });
my $even_supply = $supply.grep({ not $_ % 2 });
$even_supply.tap(-> $v { say "Even : $v" });
for 0 .. 10 {
    $supplier.emit($_);
}

map returns a new supply such that for each item emitted to the original supply a new item which is the result of the expression passed to the map is emitted:

my $supplier = Supplier.new;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "Original : $v" });
my $half_supply = $supply.map({ $_ / 2 });
$half_supply.tap(-> $v { say "Half : $v" });
for 0 .. 10 {
    $supplier.emit($_);
}

If you need to have an action that runs when the supply finishes, you can do so by setting the done and quit options in the call to tap:

$supply.tap: { ... }, 
     done => { say 'Job is done.' }, 
     quit => { 
         when X::MyApp::Error { say "App Error: ", $_.message } 
     }; 

The quit block works very similar to a CATCH. If the exception is marked as seen by a when or default block, the exception is caught and handled. Otherwise, the exception continues to up the call tree (i.e., the same behavior as when quit is not set).

If you are using the react or supply block syntax with whenever, you can add phasers within your whenever blocks to handle the done and quit messages from the tapped supply:

react { 
     whenever $supply { 
         ...; # your usual supply tap code here 
         LAST { say 'Job is done.' } 
         QUIT { when X::MyApp::Error { say "App Error: ", $_.message } } 
     } 
 } 

The behavior here is the same as setting done and quit on tap.

Channels

A Channel is a thread-safe queue that can have multiple readers and writers that could be considered to be similar in operation to a "fifo" or named pipe except it does not enable inter-process communication. It should be noted that, being a true queue, each value sent to the Channel will only be available to a single reader on a first read, first served basis: if you want multiple readers to be able to receive every item sent you probably want to consider a Supply.

An item is queued onto the Channel with the method send, and the method receive removes an item from the queue and returns it, blocking until a new item is sent if the queue is empty:

my $channel = Channel.new;
$channel.send('Channel One');
say $channel.receive;  # OUTPUT: «Channel One␤»

If the channel has been closed with the method close then any send will cause the exception X::Channel::SendOnClosed to be thrown, and a receive will throw a X::Channel::ReceiveOnClosed if there are no more items on the queue.

The method list returns all the items on the Channel and will block until further items are queued unless the channel is closed:

my $channel = Channel.new;
await (^10).map: -> $r {
    start {
        sleep $r;
        $channel.send($r);
    }
}
$channel.close;
for $channel.list -> $r {
    say $r;
}

There is also the non-blocking method poll that returns an available item from the channel or Nil if there is no item or the channel is closed, this does of course mean that the channel must be checked to determine whether it is closed:

my $c = Channel.new;

# Start three Promises that sleep for 1..3 seconds, and then
# send a value to our Channel
^3 .map: -> $v {
    start {
        sleep 3 - $v;
        $c.send: "$v from thread {$*THREAD.id}";
    }
}

# Wait 3 seconds before closing the channel
Promise.in(3).then: { $c.close }

# Continuously loop and poll the channel, until it's closed
my $is-closed = $c.closed;
loop {
    if $c.poll -> $item {
        say "$item received after {now - INIT now} seconds";
    }
    elsif $is-closed {
        last;
    }

    say 'Doing some unrelated things...';
    sleep .6;
}

# Doing some unrelated things...
# Doing some unrelated things...
# 2 from thread 5 received after 1.2063182 seconds
# Doing some unrelated things...
# Doing some unrelated things...
# 1 from thread 4 received after 2.41117376 seconds
# Doing some unrelated things...
# 0 from thread 3 received after 3.01364461 seconds
# Doing some unrelated things...

The method closed returns a Promise that will be kept (and consequently will evaluate to True in a boolean context) when the channel is closed.

The .poll method can be used in combination with .receive method, as a caching mechanism where lack of value returned by .poll is a signal that more values need to be fetched and loaded into the channel:

sub get-value { 
     return $c.poll // do { start replenish-cache; $c.receive }; 
 } 
 
 sub replenish-cache { 
     for ^20 { 
         $c.send: $_ for slowly-fetch-a-thing(); 
     } 
 } 

Channels can be used in place of the Supply in the whenever of a react block described earlier:

my $channel = Channel.new; 
 my $p = start { 
     react { 
         whenever $channel { 
             say $_; 
         } 
     } 
 } 
 
 await (^10).map: -> $r { 
     start { 
         sleep $r; 
         $channel.send($r); 
     } 
 } 
 
 $channel.close; 
 await $p; 

It is also possible to obtain a Channel from a Supply using the Channel method which returns a Channel which is fed by a tap on the Supply:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;
my $channel = $supply.Channel;

my $p = start {
    react  {
        whenever $channel -> $item {
            say "via Channel: $item";
        }
    }
}

await (^10).map: -> $r {
    start {
        sleep $r;
        $supplier.emit($r);
    }
}

$supplier.done;
await $p;

Channel will return a different Channel fed with the same data each time it is called. This could be used, for instance, to fan-out a Supply to one or more Channels to provide for different interfaces in a program.

Proc::Async

Proc::Async builds on the facilities described to run and interact with an external program asynchronously:

my $proc = Proc::Async.new('echo', 'foo', 'bar');

$proc.stdout.tap(-> $v { print "Output: $v" });
$proc.stderr.tap(-> $v { print "Error:  $v" });

say "Starting...";
my $promise = $proc.start;

await $promise;
say "Done.";

# Output:
# Starting...
# Output: foo bar
# Done.

The path to the command as well as any arguments to the command are supplied to the constructor. The command will not be executed until start is called, which will return a Promise that will be kept when the program exits. The standard output and standard error of the program are available as Supply objects from the methods stdout and stderr respectively which can be tapped as required.

If you want to write to the standard input of the program you can supply the :w adverb to the constructor and use the methods write, print or say to write to the opened pipe once the program has been started:

my $proc = Proc::Async.new(:w, 'grep', 'foo');

$proc.stdout.tap(-> $v { print "Output: $v" });

say "Starting...";
my $promise = $proc.start;

$proc.say("this line has foo");
$proc.say("this one doesn't");

$proc.close-stdin;
await $promise;
say "Done.";

# Output:
# Starting...
# Output: this line has foo
# Done.

Some programs (such as grep without a file argument in this example, ) won't exit until their standard input is closed so close-stdin can be called when you are finished writing to allow the Promise returned by start to be kept.

Low-level APIs

Threads

The lowest level interface for concurrency is provided by Thread. A thread can be thought of as a piece of code that may eventually be run on a processor, the arrangement for which is made almost entirely by the virtual machine and/or operating system. Threads should be considered, for all intents, largely un-managed and their direct use should be avoided in user code.

A thread can either be created and then actually run later:

my $thread = Thread.new(code => { for  1 .. 10  -> $v { say $v }});
# ...
$thread.run;

Or can be created and run at a single invocation:

my $thread = Thread.start({ for  1 .. 10  -> $v { say $v }});

In both cases the completion of the code encapsulated by the Thread object can be waited on with the finish method which will block until the thread completes:

$thread.finish; 

Beyond that there are no further facilities for synchronization or resource sharing which is largely why it should be emphasized that threads are unlikely to be useful directly in user code.

Schedulers

The next level of the concurrency API is supplied by classes that implement the interface defined by the role Scheduler. The intent of the scheduler interface is to provide a mechanism to determine which resources to use to run a particular task and when to run it. The majority of the higher level concurrency APIs are built upon a scheduler and it may not be necessary for user code to use them at all, although some methods such as those found in Proc::Async, Promise and Supply allow you to explicitly supply a scheduler.

The current default global scheduler is available in the variable $*SCHEDULER.

The primary interface of a scheduler (indeed the only method required by the Scheduler interface) is the cue method:

method cue(:&code, Instant :$at, :$in, :$every, :$times = 1; :&catch)

This will schedule the Callable in &code to be executed in the manner determined by the adverbs (as documented in Scheduler) using the execution scheme as implemented by the scheduler. For example:

my $i = 0;
my $cancellation = $*SCHEDULER.cue({ say $i++}, every => 2 );
sleep 20;

Assuming that the $*SCHEDULER hasn't been changed from the default, will print the numbers 0 to 10 approximately (i.e with operating system scheduling tolerances) every two seconds. In this case the code will be scheduled to run until the program ends normally, however the method returns a Cancellation object which can be used to cancel the scheduled execution before normal completion:

my $i = 0;
my $cancellation = $*SCHEDULER.cue({ say $i++}, every => 2 );
sleep 10;
$cancellation.cancel;
sleep 10;

should only output 0 to 5,

Despite the apparent advantage the Scheduler interface provides over that of Thread all of functionality is available through higher level interfaces and it shouldn't be necessary to use a scheduler directly, except perhaps in the cases mentioned above where a scheduler can be supplied explicitly to certain methods.

A library may wish to provide an alternative scheduler implementation if it has special requirements, for instance a UI library may want all code to be run within a single UI thread, or some custom priority mechanism may be required, however the implementations provided as standard and described below should suffice for most user code.

ThreadPoolScheduler

The ThreadPoolScheduler is the default scheduler, it maintains a pool of threads that are allocated on demand, creating new ones as necessary up to maximum number given as a parameter when the scheduler object was created (the default is 16.) If the maximum is exceeded then cue may queue the code until such time as a thread becomes available.

Rakudo allows the maximum number of threads allowed in the default scheduler to be set by the environment variable RAKUDO_MAX_THREADS at the time the program is started.

CurrentThreadScheduler

The CurrentThreadScheduler is a very simple scheduler that will always schedule code to be run straight away on the current thread. The implication is that cue on this scheduler will block until the code finishes execution, limiting its utility to certain special cases such as testing.

Locks

The class Lock provides the low level mechanism that protects shared data in a concurrent environment and is thus key to supporting thread-safety in the high level API, this is sometimes known as a "Mutex" in other programming languages. Because the higher level classes (Promise, Supply and Channel) use a Lock where required it is unlikely that user code will need to use a Lock directly.

The primary interface to Lock is the method protect which ensures that a block of code (commonly called a "critical section") is only executed in one thread at a time:

my $lock = Lock.new;

my $a = 0;

await (^10).map: {
    start {
        $lock.protect({
            my $r = rand;
            sleep $r;
            $a++;
        });
    }
}

say $a; # OUTPUT: «10␤»

protect returns whatever the code block returns.

Because protect will block any threads that are waiting to execute the critical section the code should be as quick as possible.

Safety Concerns

Some shared data concurrency issues are less obvious than others. For a good general write-up on this subject see this blog post.

One particular issue of note is when container autovivification or extension takes place. When an Array or a Hash entry is initially assigned the underlying structure is altered and that operation is not async safe. For example, in this code:

my @array;
my $slot := @array[20];
$slot = 'foo';

The third line is the critical section as that is when the array is extended. The simplest fix is to use a Lock to protect the critical section. A possibly better fix would be to refactor the code so that sharing a container is not necessary.

12 Containers

A low-level explanation of Perl 6 containers

This section explains the levels of indirection involved in dealing with variables and container elements. The difference types of containers used in Perl 6 are explained and the actions applicable to them like assigning, binding and flattening. More advanced topics like self-referencial data, type constraints and custom containers are discussed at the end.

What is a variable?

Some people like to say "everything is an object", but in fact a variable is not a user-exposed object in Perl 6.

When the compiler encounters a variable declaration like my $x, it registers it in some internal symbol table. This internal symbol table is used to detect undeclared variables and to tie the code generation for the variable to the correct scope.

At runtime, a variable appears as an entry in a lexical pad, or lexpad for short. This is a per-scope data structure that stores a pointer for each variable.

In the case of my $x, the lexpad entry for the variable $x is a pointer to an object of type Scalar, usually just called the container.

Scalar containers

Although objects of type Scalar are everywhere in Perl 6, you rarely see them directly as objects, because most operations decontainerize, which means they act on the Scalar container's contents instead of the container itself.

In code like

my $x = 42;
say $x;

the assignment $x = 42 stores a pointer to the Int object 42 in the scalar container to which the lexpad entry for $x points.

The assignment operator asks the container on the left to store the value on its right. What exactly that means is up to the container type. For Scalar it means "replace the previously stored value with the new one".

Note that subroutine signatures allow passing around of containers:

sub f($a is rw) {
    $a = 23;
}
my $x = 42;
f($x);
say $x;         # OUTPUT: «23␤»

Inside the subroutine, the lexpad entry for $a points to the same container that $x points to outside the subroutine. Which is why assignment to $a also modifies the contents of $x.

Likewise a routine can return a container if it is marked as is rw:

my $x = 23;
sub f() is rw { $x };
f() = 42;
say $x;         # OUTPUT: «42␤»

For explicit returns, return-rw instead of return must be used.

Returning a container is how is rw attribute accessors work. So

class A {
    has $.attr is rw;
}

is equivalent to

class A {
    has $!attr;
    method attr() is rw { $!attr }
}

Scalar containers are transparent to type checks and most kinds of read-only accesses. A .VAR makes them visible:

my $x = 42;
say $x.^name;       # OUTPUT: «Int␤»
say $x.VAR.^name;   # OUTPUT: «Scalar␤»

And is rw on a parameter requires the presence of a writable Scalar container:

sub f($x is rw) { say $x };
f 42;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Parameter::RW: Parameter '$x' expected a writable container, but got Int value␤»

Callable containers

Callable containers provide a bridge between the syntax of a Routine call and the actual call of the method CALL-ME of the object that is stored in the container. The sigil & is required when declaring the container and has to be omitted when executing the Callable. The default type constraint is Callable.

my &callable = -> $ν { say "$ν is", $ν ~~ Int??" whole"!!" not whole" }
callable( ⅓ );
callable( 3 );

The sigil has to be provided when referring to the value stored in the container. This in turn allows Routines to be used as arguments to calls.

sub f() {}
my &g = sub {}
sub caller(&c1, &c2){ c1, c2 }
caller(&f, &g);

Binding

Next to assignment, Perl 6 also supports binding with the := operator. When binding a value or a container to a variable, the lexpad entry of the variable is modified (and not just the container it points to). If you write

my $x := 42;

then the lexpad entry for $x directly points to the Int 42. Which means that you cannot assign to it anymore:

my $x := 42;
$x = 23;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot assign to an immutable value␤»

You can also bind variables to other variables:

my $a = 0;
my $b = 0;
$a := $b;
$b = 42;
say $a;         # OUTPUT: «42␤»

Here, after the initial binding, the lexpad entries for $a and $b both point to the same scalar container, so assigning to one variable also changes the contents of the other.

You've seen this situation before: it is exactly what happened with the signature parameter marked as is rw.

Sigilless variables and parameters with the trait is raw always bind (whether = or := is used):

my $a = 42;
my \b = $a;
b++;
say $a;         # OUTPUT: «43␤»

sub f($c is raw) { $c++ }
f($a);
say $a;         # OUTPUT: «44␤»

Scalar containers and listy things

There are a number of positional container types with slightly different semantics in Perl 6. The most basic one is List; it is created by the comma operator.

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

A list is immutable, which means you cannot change the number of elements in a list. But if one of the elements happens to be a scalar container, you can still assign to it:

my $x = 42;
($x, 1, 2)[0] = 23;
say $x;                 # OUTPUT: «23␤»
($x, 1, 2)[1] = 23;     # Cannot modify an immutable value
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»

So the list doesn't care about whether its elements are values or containers, they just store and retrieve whatever was given to them.

Lists can also be lazy; in that case, elements at the end are generated on demand from an iterator.

An Array is just like a list, except that it forces all its elements to be containers, which means that you can always assign to elements:

my @a = 1, 2, 3;
@a[0] = 42;
say @a;         # OUTPUT: «[42 2 3]␤»

@a actually stores three scalar containers. @a[0] returns one of them, and the assignment operator replaces the integer value stored in that container with the new one, 42.

Assigning and binding to array variables

Assignment to a scalar variable and to an array variable both do the same thing: discard the old value(s), and enter some new value(s).

Nevertheless, it's easy to observe how different they are:

my $x = 42; say $x.^name;   # OUTPUT: «Int␤»
my @a = 42; say @a.^name;   # OUTPUT: «Array␤»

This is because the Scalar container type hides itself well, but Array makes no such effort. Also assignment to an array variable is coercive, so you can assign a non-array value to an array variable.

To place a non-Array into an array variable, binding works:

my @a := (1, 2, 3);
say @a.^name;               # OUTPUT: «List␤»

Binding to array elements

As a curious side note, Perl 6 supports binding to array elements:

my @a = (1, 2, 3);
@a[0] := my $x;
$x = 42;
say @a;                     # OUTPUT: «[42 2 3]␤»

If you've read and understood the previous explanations, it is now time to wonder how this can possibly work. After all, binding to a variable requires a lexpad entry for that variable, and while there is one for an array, there aren't lexpad entries for each array element, because you cannot expand the lexpad at runtime.

The answer is that binding to array elements is recognized at the syntax level and instead of emitting code for a normal binding operation, a special method (called BIND-KEY) is called on the array. This method handles binding to array elements.

Note that, while supported, one should generally avoid directly binding uncontainerized things into array elements. Doing so may produce counter-intuitive results when the array is used later.

my @a = (1, 2, 3);
@a[0] := 42;         # This is not recommended, use assignment instead.
my $b := 42;
@a[1] := $b;         # Nor is this.
@a[2] = $b;          # ...but this is fine.
@a[1, 2] := 1, 2;    # runtime error: X::Bind::Slice
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Array slice␤»

Operations that mix Lists and Arrays generally protect against such a thing happening accidentally.

Flattening, items and containers

The % and @ sigils in Perl 6 generally indicate multiple values to an iteration construct, whereas the $ sigil indicates only one value.

my @a = 1, 2, 3;
for @a { };         # 3 iterations
my $a = (1, 2, 3);
for $a { };         # 1 iteration

@-sigiled variables do not flatten in list context:

my @a = 1, 2, 3;
my @b = @a, 4, 5;
say @b.elems;               # OUTPUT: «3␤»

There are operations that flatten out sublists that are not inside a scalar container: slurpy parameters (*@a) and explicit calls to flat:

my @a = 1, 2, 3;
say (flat @a, 4, 5).elems;  # OUTPUT: «5␤»

sub f(*@x) { @x.elems };
say f @a, 4, 5;             # OUTPUT: «5␤»

You can also use | to create a Slip, introducing a list into the other.

my @l := 1, 2, (3, 4, (5, 6)), [7, 8, (9, 10)];
say (|@l, 11, 12); # OUTPUT: «(1 2 (3 4 (5 6)) [7 8 (9 10)] 11 12)␤»
say (flat @l, 11, 12) # OUTPUT: «(1 2 3 4 5 6 7 8 (9 10) 11 12)␤»

In the first case, every element of @l is slipped as the corresponding elements of the resulting list. flat, in the other hand, flattens all elements including the elements of the included array, except for (9 10).

As hinted above, scalar containers prevent that flattening:

sub f(*@x) { @x.elems };
my @a = 1, 2, 3;
say f $@a, 4, 5;            # OUTPUT: «3␤»

The @ character can also be used as a prefix to coerce the argument to a list, thus removing a scalar container:

my $x = (1, 2, 3);
.say for @$x;               # 3 iterations

However, the decont operator <> is more appropriate to decontainerize items that aren't lists:

my $x = ^Inf .grep: *.is-prime;
say "$_ is prime" for @$x;  # WRONG! List keeps values, thus leaking memory
say "$_ is prime" for $x<>; # RIGHT. Simply decontainerize the Seq

my $y := ^Inf .grep: *.is-prime; # Even better; no Scalars involved at all

Methods generally don't care whether their invocant is in a scalar, so

my $x = (1, 2, 3);
$x.map(*.say);              # 3 iterations

maps over a list of three elements, not of one.

Self-Referential Data

Containers types, including Array and Hash, allow you to create self-referential structures.

my @a;
@a[0] = @a;
put @a.perl;
# OUTPUT: «((my @Array_75093712) = [@Array_75093712,])␤»

Perl 6 does not prevent you from creating and using self-referential data; You may end up in a loop trying to dump the data; as a last resort, you can use Promises to handle timeouts.

Type constraints

Any container can have a type constraint in the form of a type object or a subset. Both can be placed between a declarator and the variable name or after the trait of. The constraint is a property of the variable, not the container.

subset Three-letter of Str where .chars == 3;
my Three-letter $acronym = "ÞFL";

In this case, the type constraint is the (compile-type defined) subset Three-letter.

Variables may have no container in them, yet still offer the ability to re-bind and typecheck that rebind. The reason for that is in such cases the binding operator := performs the typecheck:

my Int \z = 42;
z := 100; # OK
z := "x"; # Typecheck failure

The same isn't the case when, say, binding to a Hash key, as the binding is then handled by a method call (even though the syntax remains the same, using := operator).

The default type constraint of a Scalar container is Mu. Introspection of type constraints on containers is provided by .VAR.of method, which for @ and % sigiled variables gives the constraint for values:

my Str $x;
say $x.VAR.of;  # OUTPUT: «(Str)␤»
my Num @a;
say @a.VAR.of;  # OUTPUT: «(Num)␤»
my Int %h;
say %h.VAR.of;  # OUTPUT: «(Int)␤»

Definedness Constraints

A container can also enforce a variable to be defined. Put a smiley in the declaration:

my Int:D $def = 3;
say $def; # OUTPUT: «3␤»
$def = Int; # Typecheck failure

You'll also need to initialize the variable in the declaration, it can't be left undefined after all.

It's also possible to have this constraint enforced in all variables declared in a scope with the default defined variables pragma. People coming from other languages where variables are always defined will want to have a look.

Custom containers

To provide custom containers Perl 6 provides the class Proxy. It takes two methods that are called when values are stored or fetched from the container. Type checks are not done by the container itself and other restrictions like readonlyness can be broken. The returned value must therefore be of the same type as the type of the variable it is bound to. We can use type captures to work with types in Perl 6.

sub lucky(::T $type) {
    my T $c-value; # closure variable
    return Proxy.new(
        FETCH => method () { $c-value },
        STORE => method (T $new-value) {
            X::OutOfRange.new(what => 'number', got => '13', range => '-∞..12, 14..∞').throw
                if $new-value == 13;
            $c-value = $new-value;
        }
    );
}

my Int $a := lucky(Int);
say $a = 12;    # OUTPUT: «12␤»
say $a = 'FOO'; # X::TypeCheck::Binding
say $a = 13;    # X::OutOfRange
CATCH { default { say .^name, ': ', .Str } };

13 Contexts and contextualizers

What are contexts and how to get into them

A context is needed, in many occasions, to interpret the value of a container. In Perl 6, we will use context to coerce the value of a container into some type or class, or decide what to do with it, as in the case of the sink context.

Sink

Sink is equivalent to void context, that is, a context in which we throw (down the sink, as it were) the result of an operation or the return value from a block. In general, this context will be invoked in warnings and errors when a statement does not know what to do with that value.

my $sub = -> $a { return $a² }; 
 $sub; # OUTPUT: «WARNINGS:␤Useless use of $sub in sink context (line 1)␤» 

You can force that sink context on Iterators, by using the sink-all method. Procs can also be sunk via the sink method, forcing them to raise an exception and not returning anything.

In general, blocks will warn if evaluated in sink context; however, gather/take blocks are explicitly evaluated in sink context, with values returned explicitly using take.

In sink context, an object will call its sink method if present:

sub foo { 
     return [<a b c>] does role { 
         method sink { say "sink called" } 
     } 
 } 
 foo 
 # OUTPUT: sink called 

Number

This context, and probably all of them except sink above, are conversion or interpretation contexts in the sense that they take an untyped or typed variable and duck-type it to whatever is needed to perform the operation. In some cases that will imply a conversion (from Str to Numeric, for instance); in other cases simply an interpretation (IntStr will be interpreted as Int or as Str).

Number context is called whenever we need to apply a numerical operation on a variable.

my $not-a-string="1                 "; 
 my $neither-a-string="3                        "; 
 say $not-a-string+$neither-a-string; # OUTPUT: «4␤» 

In the code above, strings will be interpreted in numeric context as long as there is only some numbers and no other characters. It can have any number of leading or trailing whitespace, however.

Numeric context can be forced by using arithmetic operators such as + or -. In that context, the Numeric method will be called if available and the value returned used as the numeric value of the object.

my $t = True; 
 my $f = False; 
 say $t+$f;      # OUTPUT: «1␤» 
 say $t.Numeric; # OUTPUT: «1␤» 
 say $f.Numeric; # OUTPUT: «0␤» 
 my $list= <a b c>; 
 say True+$list; # OUTPUT: «4␤» 

In the case of listy things, the numeric value will be in general equivalent to .elems; in some cases, like Thread it will return an unique thread identifier.

String

In a string context, values can be manipulated as strings. This context is used, for instance, for coercing non-string values so that they can be printed to standard output.

    say $very-complicated-and-hairy-object; # OUTPUT: something meaningful 

Or when smartmatching to a regular expression:

say 333444777 ~~ /(3+)/; # OUTPUT: «「333」␤ 0 => 「333」␤»

In general, the Str routine will be called on a variable to contextualize it; since this method is inherited from Mu, it is always present, but it is not always guaranteed to work. In some core classes it will issue a warning.

~ is the (unary) string contextualizer. As an operator, it concatenates strings, but as a prefix operator it becomes the string context operator.

my @array = [ [1,2,3], [4,5,6]]; 
 say ~@array; # OUTPUT: «1 2 3 4 5 6␤» 

This will happen also in a reduction context, when [~] is applied to a list

say [~] [ 3, 5+6i, Set(<a b c>), [1,2,3] ]; # OUTPUT: «35+6ic a b1 2 3␤»

In that sense, empty lists or other containers will stringify to an empty string:

say [~] [] ; # OUTPUT: «␤»

Since ~ acts also as buffer concatenation operator, using it will have to check that every element is not empty, since a single empty buffer in string context will behave as a string, thus yielding an error.

say [~] Buf.new(0x3,0x33), Buf.new(0x2,0x22);
# OUTPUT: «Buf:0x<03 33 02 22>␤»

However,

my $non-empty = Buf.new(0x3, 0x33); 
 my $empty = []; 
 my $non-empty-also = Buf.new(0x2,0x22); 
 say [~] $non-empty, $empty, $non-empty-also; 
 # OUTPUT: «(exit code 1) Cannot use a Buf as a string, but you called the Stringy method on it 
 # in block <unit> at /tmp/bO_heb6AS9 line 1␤␤» 

Since ~ is putting in string context the second element of this list, ~ is going to be using the second form that applies to strings, thus yielding the shown error. Simply making sure that everything you concatenate is a buffer will avoid this problem.

my $non-empty = Buf.new(0x3, 0x33);
my $empty = Buf.new();
my $non-empty-also = Buf.new(0x2,0x22);
say [~] $non-empty, $empty, $non-empty-also; # OUTPUT: «Buf:0x<03 33 02 22>␤»

14 Control Flow

Statements used to control the flow of execution

statements

Perl 6 programs consists of one or more statements. Simple statements are separated by semicolons. The following program will say "Hello" and then say "World" on the next line.

say "Hello";
say "World";

In most places where spaces appear in a statement, and before the semicolon, it may be split up over many lines. Also, multiple statements may appear on the same line. It would be awkward, but the above could also be written as:

say
"Hello"; say "World";

blocks

Like many languages, Perl 6 uses blocks enclosed by { and } to turn multiple statements into a single statement. It is ok to skip the semicolon between the last statement in a block and the closing }.

{ say "Hello"; say "World" }

When a block stands alone as a statement, it will be entered immediately after the previous statement finishes, and the statements inside it will be executed.

say 1;                    # OUTPUT: «1␤»
{ say 2; say 3 };         # OUTPUT: «2␤3␤»
say 4;                    # OUTPUT: «4␤»

Unless it stands alone as a statement, a block simply creates a closure. The statements inside are not executed immediately. Closures are another topic and how they are used is explained elsewhere. For now it is just important to understand when blocks run and when they do not:

say "We get here"; { say "then here." }; { say "not here"; 0; } or die; 

In the above example, after running the first statement, the first block stands alone as a second statement, so we run the statement inside it. The second block does not stand alone as a statement, so instead, it makes an object of type Block but does not run it. Object instances are usually considered to be true, so the code does not die, even though that block would evaluate to 0, were it to be executed. The example does not say what to do with the Block object, so it just gets thrown away.

Most of the flow control constructs covered below are just ways to tell perl6 when, how, and how many times, to enter blocks like that second block.

Before we go into those, an important side-note on syntax: If there is nothing (or nothing but comments) on a line after a closing curly brace where you would normally put semicolon, then you do not need the semicolon:

# All three of these lines can appear as a group, as is, in a program
{ 42.say }                # OUTPUT: «42␤»
{ 43.say }                # OUTPUT: «43␤»
{ 42.say }; { 43.say }    # OUTPUT: «42␤43␤»

...but:

{ 42.say }  { 43.say }    # Syntax error 
 { 42.say; } { 43.say }    # Also a syntax error, of course 

So, be careful when you backspace in a line-wrapping editor:

{ "Without semicolons line-wrapping can be a bit treacherous.".say } \ 
 { 43.say } # Syntax error 

You have to watch out for this in most languages anyway to prevent things from getting accidentally commented out. Many of the examples below may have unnecessary semicolons for clarity.

do

The simplest way to run a block where it cannot be a stand-alone statement is by writing do before it:

# This dies half of the time 
 do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win."; 

Note that you need a space between the do and the block.

The whole do {...} evaluates to the final value of the block. The block will be run when that value is needed in order to evaluate the rest of the expression. So:

False and do { 42.say };

...will not say 42. However, the block is only evaluated once each time the expression it is contained in is evaluated:

# This says "(..1 ..2 ..3)" not "(..1 ...2 ....3)"
my $f = "."; say do { $f ~= "." } X~ 1, 2, 3;

In other words, it follows the same reification rules as everything else.

Technically, do is a loop which runs exactly one iteration.

A do may also be used on a bare statement (without curly braces) but this is mainly just useful for avoiding the syntactical need to parenthesize a statement if it is the last thing in an expression:

3, do if 1 { 2 }  ; # OUTPUT: «(3, 2)␤» 
 3,   (if 1 { 2 }) ; # OUTPUT: «(3, 2)␤» 
3,    if 1 { 2 }  ; # Syntax error 

...which brings us to if.

if

To conditionally run a block of code, use an if followed by a condition. The condition, an expression, will be evaluated immediately after the statement before the if finishes. The block attached to the condition will only be evaluated if the condition means True when coerced to Bool. Unlike some languages the condition does not have to be parenthesized, instead the { and } around the block are mandatory:

if 1 { "1 is true".say }  ; # says "1 is true" 
if 1   "1 is true".say    ; # syntax error, missing block 
if 0 { "0 is true".say }  ; # does not say anything, because 0 is false 
if 42.say and 0 { 43.say }; # says "42" but does not say "43" 

There is also a form of if called a "statement modifier" form. In this case, the if and then the condition come after the code you want to run conditionally. Do note that the condition is still always evaluated first:

43.say if 42.say and 0;     # says "42" but does not say "43"
43.say if 42.say and 1;     # says "42" and then says "43"
say "It is easier to read code when 'if's are kept on left of screen"
    if True;                # says the above, because it is true
{ 43.say } if True;         # says "43" as well

The statement modifier form is probably best used sparingly.

The if statement itself will either slip us an empty list, if it does not run the block, or it will return the value which the block produces:

my $d = 0; say (1, (if 0 { $d += 42; 2; }), 3, $d); # says "(1 3 0)"
my $c = 0; say (1, (if 1 { $c += 42; 2; }), 3, $c); # says "(1 2 3 42)"
say (1, (if 1 { 2, 2 }), 3);         # does not slip, says "(1 (2 2) 3)"

For the statement modifier it is the same, except you have the value of the statement instead of a block:

say (1, (42 if True) , 2); # says "(1 42 2)"
say (1, (42 if False), 2); # says "(1 2)"
say (1,  42 if False , 2); # says "(1 42)" because "if False, 2" is true

The if does not change the topic ($_) by default. In order to access the value which the conditional expression produced, you have to ask for it more strongly:

$_ = 1; if 42 { $_.say }                ; # says "1"
$_ = 1; if 42 -> $_ { $_.say }          ; # says "42"
$_ = 1; if 42 -> $a { $_.say;  $a.say } ; # says "1" then says "42"
$_ = 1; if 42       { $_.say; $^a.say } ; # says "1" then says "42"

else/elsif

A compound conditional may be produced by following an if conditional with else to provide an alternative block to run when the conditional expression is false:

if 0 { say "no" } else { say "yes" }   ; # says "yes" 
 if 0 { say "no" } else{ say "yes" }    ; # says "yes", space is not required 

The else cannot be separated from the conditional statement by a semicolon, but as a special case, it is OK to have a newline.

if 0 { say "no" }; else { say "yes" }  ; # syntax error 
if 0 { say "no" } 
 else { say "yes" }                     ; # says "yes" 

Additional conditions may be sandwiched between the if and the else using elsif. An extra condition will only be evaluated if all the conditions before it were false, and only the block next to the first true condition will be run. You can end with an elsif instead of an else if you want.

if 0 { say "no" } elsif False { say "NO" } else { say "yes" } # says "yes"
if 0 { say "no" } elsif True { say "YES" } else { say "yes" } # says "YES"

if 0 { say "no" } elsif False { say "NO" } # does not say anything

sub right { "Right!".say; True }
sub wrong { "Wrong!".say; False }
if wrong() { say "no" } elsif right() { say "yes" } else { say "maybe" }
# The above says "Wrong!" then says "Right!" then says "yes"

You cannot use the statement modifier form with else or elsif:

42.say if 0 else { 43.say }            # syntax error 

All the same rules for semicolons and newlines apply, consistently

if 0 { say 0 }; elsif 1 { say 1 }  else { say "how?" } ; # syntax error 
 if 0 { say 0 }  elsif 1 { say 1 }; else { say "how?" } ; # syntax error 
 if 0 { say 0 }  elsif 1 { say 1 }  else { say "how?" } ; # says "1" 
if 0 { say 0 } elsif 1 { say 1 }
else { say "how?" }                                    ; # says "1"

if 0 { say 0 }
elsif 1 { say 1 } else { say "how?" }                  ; # says "1"

if        0 { say "no" }
elsif False { say "NO" }
else        { say "yes" }                              ; # says "yes"

The whole thing either slips us an empty list (if no blocks were run) or returns the value produced by the block that did run:

my $d = 0; say (1,
                (if 0 { $d += 42; "two"; } elsif False { $d += 43; 2; }),
                3, $d); # says "(1 3 0)"
my $c = 0; say (1,
                (if 0 { $c += 42; "two"; } else { $c += 43; 2; }),
                3, $c); # says "(1 2 3 43)"

It's possible to obtain the value of the previous expression inside an else, which could be from if or the last elsif if any are present:

$_ = 1; if 0     { } else -> $a { "$_ $a".say } ; # says "1 0"
$_ = 1; if False { } else -> $a { "$_ $a".say } ; # says "1 False"

if False { } elsif 0 { } else -> $a { $a.say }  ; # says "0"

unless

When you get sick of typing "if not (X)" you may use unless to invert the sense of a conditional statement. You cannot use else or elsif with unless because that ends up getting confusing. Other than those two differences unless works the same as #if:

unless 1 { "1 is false".say }  ; # does not say anything, since 1 is true 
unless 1   "1 is false".say    ; # syntax error, missing block 
unless 0 { "0 is false".say }  ; # says "0 is false" 
unless 42.say and 1 { 43.say } ; # says "42" but does not say "43"
43.say unless 42.say and 0;      # says "42" and then says "43"
43.say unless 42.say and 1;      # says "42" but does not say "43"

$_ = 1; unless 0 { $_.say }           ; # says "1"
$_ = 1; unless 0 -> $_ { $_.say }     ; # says "0"
$_ = 1; unless False -> $a { $a.say } ; # says "False"

my $c = 0; say (1, (unless 0 { $c += 42; 2; }), 3, $c); # says "(1 2 3 42)"
my $d = 0; say (1, (unless 1 { $d += 42; 2; }), 3, $d); # says "(1 3 0)"

with, orwith, without

The with statement is like if but tests for definedness rather than truth. In addition, it topicalizes on the condition, much like given:

with "abc".index("a") { .say }      # prints 0

Instead of elsif, orwith may be used to chain definedness tests:

# The below code says "Found a at 0"
my $s = "abc";
with   $s.index("a") { say "Found a at $_" }
orwith $s.index("b") { say "Found b at $_" }
orwith $s.index("c") { say "Found c at $_" }
else                 { say "Didn't find a, b or c" }

You may intermix if-based and with-based clauses.

# This says "Yes"
if 0 { say "No" } orwith Nil { say "No" } orwith 0 { say "Yes" };

As with unless, you may use without to check for undefinedness, but you may not add an else clause:

my $answer = Any;
without $answer { warn "Got: {$_.perl}" }

There are also with and without statement modifiers:

my $answer = (Any, True).roll;
say 42 with $answer;
warn "undefined answer" without $answer;

when

The when block is similar to an if block and either or both can be used in an outer block, they also both have a "statement modifier" form. But there is a difference in how following code in the same, outer block is handled: When the when block is executed, control is passed to the enclosing block and following statements are ignored; but when the if block is executed, following statements are executed. (Note there are other ways to modify the default behavior of each which are discussed in other sections.) The following examples should illustrate the if or when block's default behavior assuming no special exit or other side effect statements are included in the if or when blocks:

{ 
     if X {...} # if X is true in boolean context, block is executed 
     # following statements are executed regardless 
 } 
 { 
     when X {...} # if X is true in boolean context, block is executed 
                  # and control passes to the outer block 
     # following statements are NOT executed 
 } 

Should the if and when blocks above appear at file scope, following statements would be executed in each case.

There is one other feature a when has that if doesn't: the when's boolean context test defaults to $_ ~~ while the if's does not. That has an effect on how one uses the X in the when block without a value for $_ (it's Any in that case and Any smartmatches on True: Any ~~ True yields True). Consider the following:

{ 
     my $a = 1; 
     my $b = True; 
     when $a    { say 'a' }; # no output 
     when so $a { say 'a' }  # a (in "so $a" 'so' coerces $a to Boolean context True 
                             # which matches with Any) 
     when $b    { say 'b' }; # no output (this statement won't be run) 
 } 

Finally, when's statement modifier form does not effect execution of following statements either inside or outside of another block:

say "foo" when X; # if X is true statement is executed 
                   # following statements are not affected 

for

The for loop iterates over a list, running the statements inside a block once on each iteration. If the block takes parameters, the elements of the list are provided as arguments.

my @foo = 1..3;
for @foo { $_.print } # prints each value contained in @foo
for @foo { .print }   # same thing, because .print implies a $_ argument
for @foo { 42.print } # prints 42 as many times as @foo has elements

Pointy block syntax or a placeholder may be used to name the parameter, of course.

my @foo = 1..3;
for @foo -> $item { print $item }
for @foo { print $^item }            # same thing

Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.

my @foo = 1..3;
for @foo.kv -> $idx, $val { say "$idx: $val" }
my %hash = <a b c> Z=> 1,2,3;
for %hash.kv -> $key, $val { say "$key => $val" }
for 1, 1.1, 2, 2.1 { say "$^x < $^y" }  # says "1 < 1.1" then says "2 < 2.1"

Parameters of a pointy block can have default values, allowing to handle lists with missing elements.

my @list = 1,2,3,4;
for @list -> $a, $b = 'N/A', $c = 'N/A' {
    say "$a $b $c"
}
# OUTPUT: «1 2 3␤4 N/A N/A␤»

If the postfix form of for is used a block is not required and the topic is set for the statement list.

say „I $_ butterflies!“ for <♥ ♥ ♥>;
# OUTPUT«I ♥ butterflies!␤I ♥ butterflies!␤I ♥ butterflies!␤»

A for may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:

for $*IN.lines -> $line { .say } 

Iteration variables are always lexical, so you don't need to use my to give them the appropriate scope. Also, they are read-only aliases. If you need them to be read-write, use <-> instead of ->. If you need to make $_ read-write in a for loop, do so explicitly.

my @foo = 1..3;
for @foo <-> $_ { $_++ }

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:

(for 1, 2, 3 { $_ * 2 }).say;              # says "(2 4 6)"
my @a = do for 1, 2, 3 { $_ * 2 }; @a.say; # says "[2 4 6]"
my @b = (for 1, 2, 3 { $_ * 2 }); @a.say;  # same thing

gather/take

gather is a statement or block prefix that returns a sequence of values. The values come from calls to take in the dynamic scope of the gather block.

my @a = gather {
    take 1;
    take 5;
    take 42;
}
say join ', ', @a;          # OUTPUT: «1, 5, 42␤»

gather/take can generate values lazily, depending on context. If you want to force lazy evaluation use the lazy subroutine or method. Binding to a scalar or sigilless container will also force laziness.

For example

my @vals = lazy gather {
    take 1;
    say "Produced a value";
    take 2;
}
say @vals[0];
say 'between consumption of two values';
say @vals[1];

# OUTPUT:
# 1
# between consumption of two values
# Produced a value
# 2

gather/take is scoped dynamically, so you can call take from subs or methods that are called from within gather:

sub weird(@elems, :$direction = 'forward') {
    my %direction = (
        forward  => sub { take $_ for @elems },
        backward => sub { take $_ for @elems.reverse },
        random   => sub { take $_ for @elems.pick(*) },
    );
    return gather %direction{$direction}();
}

say weird(<a b c>, :direction<backward> );          # OUTPUT: «(c b a)␤»

If values need to be mutable on the caller side, use take-rw.

given

The given statement is Perl 6's topicalizing keyword in a similar way that switch topicalizes in languages such as C. In other words, given sets $_ inside the following block. The keywords for individual cases are when and default. The usual idiom looks like this:

my $var = (Any, 21, any <answer lie>).pick;
given $var {
    when 21 { say $_ * 2 }
    when 'lie' { .say }
    default { say 'default' }
}

The given statement is often used alone:

given 42 { .say; .Numeric; }

This is a lot more understandable than:

{ .say; .Numeric; }(42)

default and when

A block containing a default statement will be left immediately when the sub-block after the default statement is left. It is as though the rest of the statements in the block are skipped.

given 42 {
    "This says".say;
    $_ == 42 and ( default { "This says, too".say; 43; } );
    "This never says".say;
}
# The above block evaluates to 43

A when statement will also do this (but a when statement modifier will not.)

In addition, when statements smartmatch the topic ($_) against a supplied expression such that it is possible to check against values, regular expressions, and types when specifying a match.

for 42, 43, "foo", 44, "bar" {
    when Int { .say }
    when /:i ^Bar/ { .say }
    default  { say "Not an Int or a Bar" }
}
# OUTPUT: «42␤43␤Not an Int or a Bar␤44␤Bar␤»

In this form, the given/when construct acts much like a set of if/elsif/else statements. Be careful with the order of the when statements. The following code says "Int" not 42.

given 42 {
    when Int { say "Int" }
    when 42  { say 42 }
    default  { say "huh?" }
}
# OUTPUT: «Int␤»

When a when statement or default statement causes the outer block to return, nesting when or default blocks do not count as the outer block, so you can nest these statements and still be in the same "switch" just so long as you do not open a new block:

given 42 {
    when Int {
      when 42  { say 42 }
      say "Int"
    }
    default  { say "huh?" }
}
# OUTPUT: «42»

when statements can smartmatch against Signatures.

proceed

succeed

Both proceed and succeed are meant to be used only from inside when or default blocks.

The proceed statement will immediately leave the when or default block, skipping the rest of the statements, and resuming after the block. This prevents the when or default from exiting the outer block.

given * { 
     default { 
         proceed; 
         "This never says".say 
     } 
 } 
 "This says".say; 

This is most often used to enter multiple when blocks. proceed will resume matching after a successful match, like so:

given 42 {
    when Int   { say "Int"; proceed }
    when 42    { say 42 }
    when 40..* { say "greater than 40" }
    default    { say "huh?" }
}
# OUTPUT: «Int␤»
# OUTPUT: «42␤»

Note that the when 40..* match didn't occur. For this to match such cases as well, one would need a proceed in the when 42 block.

This is not like a C switch statement, because the proceed does not merely enter the directly following block, it attempts to match the given value once more, consider this code:

given 42 {
    when Int { "Int".say; proceed }
    when 43  { 43.say }
    when 42  { 42.say }
    default  { "got change for an existential answer?".say }
}
# OUTPUT: «Int␤»
# OUTPUT: «42␤»

...which matches the Int, skips 43 since the value doesn't match, matches 42 since this is the next positive match, but doesn't enter the default block since the when 42 block doesn't contain a proceed.

By contrast, the succeed keyword short-circuits execution and exits the entire given block at that point. It may also take an argument to specify a final value for the block.

given 42 {
    when Int {
        say "Int";
        succeed "Found";
        say "never this!";
    }
    when 42 { say 42 }
    default { say "dunno?" }
}
# OUTPUT: «Int␤»

If you are not inside a when or default block, it is an error to try to use proceed or succeed. Also remember, the when statement modifier form does not cause any blocks to be left, and any succeed or proceed in such a statement applies to the surrounding clause, if there is one:

given 42 {
    { say "This says" } when Int;
    "This says too".say;
    when * > 41 {
       { "And this says".say; proceed } when * > 41;
       "This never says".say;
    }
    "This also says".say;
}

given as a statement

given can follow a statement to set the topic in the statement it follows.

.say given "foo";
# OUTPUT: «foo␤»

printf "%s %02i.%02i.%i",
        <Mo Tu We Th Fr Sa Su>[.day-of-week - 1],
        .day,
        .month,
        .year
    given DateTime.now;
# OUTPUT: «Sa 03.06.2016»

loop

The loop statement takes three statements in parentheses separated by ; that take the role of initializer, conditional and incrementer. The initializer is executed once and any variable declaration will spill into the surrounding block. The conditional is executed once per iteration and coerced to Bool, if False the loop is stopped. The incrementer is executed once per iteration.

loop (my $i = 0; $i < 10; $i++) {
    say $i;
}

The infinite loop does not require parentheses.

loop { say 'forever' } 

The loop statement may be used to produce values from the result of each run of the attached block if it appears in lists:

(loop ( my $i = 0; $i++ < 3;) { $i * 2 }).say;               # OUTPUT: «(2 4 6)␤»
my @a = (loop ( my $j = 0; $j++ < 3;) { $j * 2 }); @a.say;   # OUTPUT: «[2 4 6]␤»
my @b = do loop ( my $k = 0; $k++ < 3;) { $k * 2 }; @b.say;  # same thing

Unlike a for loop, one should not rely on whether returned values are produced lazily, for now. It would probably be best to use eager to guarantee that a loop whose return value may be used actually runs:

sub heads-in-a-row {
    (eager loop (; 2.rand < 1;) { "heads".say })
}

while, until

The while statement executes the block as long as its condition is true. So

my $x = 1;
while $x < 4 {
    print $x++;
}
print "\n";

# OUTPUT: «123␤»

Similarly, the until statement executes the block as long as the expression is false.

my $x = 1;
until $x > 3 {
    print $x++;
}
print "\n";

# OUTPUT: «123␤»

The condition for while or until can be parenthesized, but there must be a space between the keyword and the opening parenthesis of the condition.

Both while and until can be used as statement modifiers. E. g.

my $x = 42;
$x-- while $x > 12

Also see repeat/while and repeat/until below.

All these forms may produce a return value the same way loop does.

repeat/while, repeat/until

Executes the block at least once and, if the condition allows, repeats that execution. This differs from while/until in that the condition is evaluated at the end of the loop, even if it appears at the front.

my $x = -42;
repeat {
    $x++;
} while $x < 5;
$x.say; # OUTPUT: «5␤»

repeat {
    $x++;
} while $x < 5;
$x.say; # OUTPUT: «6␤»

repeat while $x < 10 {
    $x++;
}
$x.say; # OUTPUT: «10␤»

repeat while $x < 10 {
    $x++;
}
$x.say; # OUTPUT: «11␤»

repeat {
    $x++;
} until $x >= 15;
$x.say; # OUTPUT: «15␤»

repeat {
    $x++;
} until $x >= 15;
$x.say; # OUTPUT: «16␤»

repeat until $x >= 20 {
    $x++;
}
$x.say; # OUTPUT: «20␤»

repeat until $x >= 20 {
    $x++;
}
$x.say; # OUTPUT: «21␤»

All these forms may produce a return value the same way loop does.

return

The sub return will stop execution of a subroutine or method, run all relevant phasers and provide the given return value to the caller. The default return value is Nil. If a return type constraint is provided it will be checked unless the return value is Nil. If the type check fails the exception X::TypeCheck::Return is thrown. If it passes a control exception is raised and can be caught with CONTROL.

Any return in a block is tied to the first Routine in the outer lexical scope of that block, no matter how deeply nested. Please note that a return in the root of a package will fail at runtime. A return in a block that is evaluated lazily (e.g. inside map) may find the outer lexical routine gone by the time the block is executed. In almost any case last is the better alternative.

TODO add link to section in /language/function that shows how return values are produces/handled

return-rw

The sub return will return values, not containers. Those are immutable and will lead to runtime errors when attempted to be mutated.

sub s(){ my $a = 41; return $a };
say ++s();
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Multi::NoMatch.new(dispatcher …

To return a mutable container, use return-rw.

sub s(){ my $a = 41; return-rw $a };
say ++s();
# OUTPUT: «42␤»

The same rules as for return regarding phasers and control exceptions apply.

fail

Leaves the current routine and returns the provided Exception or Str wrapped inside a Failure, after all relevant phasers are executed. If the caller activated fatal exceptions via the pragma use fatal;, the exception is thrown instead of being returned as a Failure.

sub f { fail "WELP!" };
say f;
CATCH { default { say .^name, ': ', .Str } }
# OUTPUT: «X::AdHoc: WELP!␤»

once

A block prefix with once will be executed exactly once, even if placed inside a loop or a recursive routine.

my $guard = 3;
loop {
    last if $guard-- <= 0;
    once { put 'once' };
    print 'many'
} # OUTPUT: «once␤manymanymany»

This works per "clone" of the containing code object, so:

({ once 42.say } xx 3).map: {$_(), $_()}; # says 42 thrice

Note that this is not a thread-safe construct when the same clone of the same block is run by multiple threads. Also remember that methods only have one clone per class, not per object.

quietly

A quietly block will suppress warnings.

quietly { warn 'kaput!' };
warn 'still kaput!';
# OUTPUT: «still kaput! [...]␤»

LABELs

while, until, loop and for loops can all take a label, which can be used to identify them for next, last, and redo. Nested loops are supported, for instance:

OUTAHERE: while True  {
    for 1,2,3 -> $n {
        last OUTAHERE if $n == 2;
    }
}

Labels can be used also within nested loops to name each loop, for instance:

OUTAHERE: 
 loop ( my $i = 1; True; $i++ ) { 
   OUTFOR: 
     for 1,2,3 -> $n { 
       # exits the for loop before its natural end 
       last OUTFOR if $n == 2; 
   } 
 
   # exits the infinite loop 
   last OUTAHERE if $i >= 2; 
 } 

next

The next command starts the next iteration of the loop. So the code

my @x = 1, 2, 3, 4, 5; 
 for @x -> $x { 
     next if $x == 3; 
     print $x; 
 } 

prints "1245".

last

The last command immediately exits the loop in question.

my @x = 1, 2, 3, 4, 5; 
 for @x -> $x { 
     last if $x == 3; 
     print $x; 
 } 

prints "12".

redo

The redo command restarts the loop block without evaluating the conditional again.

loop { 
     my $x = prompt("Enter a number"); 
     redo unless $x ~~ /\d+/; 
     last; 
 } 

15 Enumeration

Using the enum type

An example using the enum type

In Perl 6 the enum type is much more complex than in some other languages, and the details are found in its type description here: enum.

This short document will give a simple example of its use similar to use in C-like languages.

Say we have a program that needs to write to various directories so we want a function that, given a directory name, tests it for (1) its existence and (2) whether it can be written to by the user of the program. The results of the test will determine what actions the program takes next.

# the directory will have one of these three statuses from the user's perspective: 
 enum DirStat <CanWrite NoDir NoWrite>; 
 sub check-dir-status($dir --> DirStat) { 
     if $dir.IO.d { 
         # dir exists, can the program user write to it? 
         my $f = "$dir/.tmp"; 
         spurt $f, "some text"; 
         CATCH { 
             # unable to write for some reason 
             return NoWrite; 
         } 
         # if we get here we must have successfully written to the dir 
         unlink $f; 
         return CanWrite; 
     } 
     # if we get here the dir must not exist 
     return NoDir; 
 } 
 
 # test each of three directories by a non-root user 
 my $dirs = 
     '/tmp',  # normally writable by any user 
     '/',     # writable only by root 
     '~/tmp'; # a non-existent dir in the user's home dir 
 for $dirs -> $dir { 
     my $stat = check-dir-status $dir; 
     say "status of dir '$dir': $stat"; 
     if $stat ~~ CanWrite { 
         say "  user can write to dir: $dir"; 
     } 
 } 
 # output 
 #   status of dir '/tmp': CanWrite 
 #     user can write to dir: /tmp 
 #   status of dir '/': NoWrite 
 #   status of dir '~/tmp': NoDir 

16 Exceptions

Using exceptions in Perl 6

Exceptions in Perl 6 are objects that hold information about errors. An error can be, for example, the unexpected receiving of data or a network connection no longer available, or a missing file. The information that an exception objects store is, for instance, a human-readable message about the error condition, the backtrace of the raising of the error, and so on.

All built-in exceptions inherit from Exception, which provides some basic behavior, including the storage of a backtrace and an interface for the backtrace printer.

Ad hoc exceptions

Ad hoc exceptions can be used by calling die with a description of the error:

die "oops, something went wrong";

# RESULT: «oops, something went wrong in block <unit> at my-script.p6:1␤»

It is worth noting that die prints the error message to the standard error $*ERR.

Typed exceptions

Typed exceptions provide more information about the error stored within an exception object.

For example, if while executing .zombie copy on an object, a needed path foo/bar becomes unavailable, then an X::IO::DoesNotExist exception can be raised:

die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"))

# RESULT: «Failed to find 'foo/bar' while trying to do '.zombie copy'
#          in block <unit> at my-script.p6:1»

Note how the object has provided the backtrace with information about what went wrong. A user of the code can now more easily find and correct the problem.

Catching exceptions

It's possible to handle exceptional circumstances by supplying a CATCH block:

die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"));

CATCH {
    when X::IO { $*ERR.say: "some kind of IO exception was caught!" }
}

# OUTPUT: «some kind of IO exception was caught!»

Here, we are saying that if any exception of type X::IO occurs, then the message some kind of IO exception was caught! will be sent to stderr, which is what $*ERR.say does, getting displayed on whatever constitutes the standard error device in that moment, which will probably be the console by default.

A CATCH block uses smartmatching similar to how given/when smartmatches on options, thus it's possible to catch and handle various categories of exceptions inside a when block.

To handle all exceptions, use a default statement. This example prints out almost the same information as the normal backtrace printer.

CATCH {
     default {
         $*ERR.say: .payload;
         for .backtrace.reverse {
             next if .file.starts-with('SETTING::');
             next unless .subname;
             $*ERR.say: "  in block {.subname} at {.file} line {.line}";
         }
     }
}

Note that the match target is a role. To allow user defined exceptions to match in the same manner, they must implement the given role. Just existing in the same namespace will look alike but won't match in a CATCH block.

Exception handlers and enclosing blocks.

After a CATCH has handled the exception, the block enclosing the CATCH block is exited.

In other words, even when the exception is handled successfully, the rest of the code in the enclosing block will never be executed.

die "something went wrong ...";

CATCH {
    # will definitely catch all the exception
    default { .Str.say; }
}

say "This won't be said.";   # but this line will be never reached since
                             # the enclosing block will be exited immediately
# OUTPUT: «something went wrong ...␤»

Compare with this:

CATCH {

  CATCH {
      default { .Str.say; }
  }

  die "something went wrong ...";

}

say "Hi! I am at the outer block!"; # OUTPUT: «Hi! I am at the outer block!␤»

See "Resuming of Exceptions", for how to return control back to where the exception originated.

try

A try block is a normal block with the use fatal pragma turned on and an implicit CATCH block that drops the exception, which means you can use it to contain them.

{ 
     my $x = +"a"; 
     say $x.^name; 
 } # OUTPUT: «Failure␤» 
 
 try { 
     my $x = +"a"; 
     say $x.^name; 
 } 

Any exception that is thrown in such a block will be caught by the implicit CATCH block or a CATCH block provided by the user. In the latter case, any unhandled exception will be rethrown. If you choose not to handle the exception, they will be contained by the block.

try { 
     die "Tough luck"; 
     say "Not gonna happen"; 
 } 
 
 try { 
     fail "FUBAR"; 
 } 

In both try blocks above, exceptions will be contained within the block, but the say statement will not be run. We can handle them, though:

class E is Exception { method message() { "Just stop already!" } }

try {
    E.new.throw; # this will be local

    say "This won't be said.";
}

say "I'm alive!";

try {
    CATCH {
        when X::AdHoc { .Str.say; .resume }
    }

    die "No, I expect you to DIE Mr. Bond!";

    say "I'm immortal.";

    E.new.throw;

    say "No, you don't!";
}

Which would output:

I'm alive! 
 No, I expect you to DIE Mr. Bond! 
 I'm immortal. 
 Just stop already! 
   in block <unit> at exception.p6 line 21 

Since the CATCH block is handling just the X::AdHoc exception thrown by the die statement, but not the E exception. In the absence of a CATCH block, all exceptions will be contained and dropped, as indicated above. resume will resume execution right after the exception has been thrown; in this case, in the die statement. Please consult the section on resuming of exceptions for more information on this.

A try-block is a normal block and as such treats its last statement as the return value of itself. We can therefore use it as a right-hand side.

say try { +"99999" } // "oh no"; # OUTPUT: «99999␤» 
 say try { +"hello" } // "oh no"; # OUTPUT: «oh no␤» 

Try blocks support else blocks indirectly by returning the return value of the expression or Nil if an exception was thrown.

with try +"♥" {
    say "this is my number: $_"
} else {
    say "not my number!"
}
# OUTPUT: «not my number!␤»

try can also be used with a statement instead of a block:

say try "some-filename.txt".IO.slurp // "sane default"; 
 # OUTPUT: «sane default␤» 

What try actually causes is, via the use fatal pragma, an immediate throw of the exceptions that happen within its scope, but by doing so the CATCH block is invoked from the point where the exception is thrown, which defines its scope.

my $error-code = "333"; 
 sub bad-sub { 
     die "Something bad happened"; 
 } 
 try { 
     my $error-code = "111"; 
     bad-sub; 
 
     CATCH { 
         default { 
             say "Error $error-code ", .^name, ': ',.Str 
         } 
     } 
 } 
 # OUTPUT: «Error 111 X::AdHoc: Something bad happened␤» 

Throwing exceptions

Exceptions can be thrown explicitly with the .throw method of an Exception object.

This example throws an AdHoc exception, catches it and allows the code to continue from the point of the exception by calling the .resume method.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {
        when X::AdHoc { .resume }
    }
}

"OBAI".say;

# OUTPUT: «OHAI␤OBAI␤»

If the CATCH block doesn't match the exception thrown, then the exception's payload is passed on to the backtrace printing mechanism.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {  }
}

"OBAI".say;

# RESULT: «foo
#          in block <unit> at my-script.p6:1»

This next example doesn't resume from the point of the exception. Instead, it continues after the enclosing block, since the exception is caught, and then control continues after the CATCH block.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {
        when X::AdHoc { }
    }
}

"OBAI".say;

# OUTPUT: «OBAI␤»

throw can be viewed as the method form of die, just that in this particular case, the sub and method forms of the routine have different names.

Resuming of Exceptions

Exceptions interrupt control flow and divert it away from the statement following the statement that threw it. Any exception handled by the user can be resumed and control flow will continue with the statement following the statement that threw the exception. To do so, call the method .resume on the exception object.

CATCH { when X::AdHoc { .resume } }         # this is step 2

die "We leave control after this.";         # this is step 1

say "We have continued with control flow."; # this is step 3

Resuming will occur right after the statement that has caused the exception, and in the innermost call frame:

sub bad-sub { 
     die "Something bad happened"; 
     return "not returning"; 
 } 
 
 { 
     my $return = bad-sub; 
     say "Returned $return"; 
     CATCH { 
         default { 
             say "Error ", .^name, ': ',.Str; 
             $return = '0'; 
             .resume; 
 
         } 
     } 
 } 
 # OUTPUT: 
 # Error X::AdHoc: Something bad happened 
 # Returned not returning 

In this case, .resume is getting to the return statement that happens right after the die statement. Please note that the assignment to $return is taking no effect, since the CATCH statement is happening inside the call to bad-sub, which, via the return statement, assigns the not returning value to it.

Uncaught Exceptions

If an exception is thrown and not caught, it causes the program to exit with a non-zero status code, and typically prints a message to the standard error stream of the program. This message is obtained by calling the gist method on the exception object. You can use this to suppress the default behavior of printing a backtrace along with the message:

class X::WithoutLineNumber is X::AdHoc {
    multi method gist(X::WithoutLineNumber:D:) {
            $.payload
    }
}
die X::WithoutLineNumber.new(payload => "message")

# prints "message\n" to $*ERR and exits, no backtrace

Control Exceptions

Control exceptions are thrown by certain keywords and are handled either automatically or by the appropriate phaser. Any unhandled control exception is converted to a normal exception.

{ return; CATCH { default { $*ERR.say: .^name, ': ',.Str } } }

# OUTPUT: «X::ControlFlow::Return: Attempt to return outside of any Routine␤»
# was CX::Return

17 Experimental Features

New features for brave users

During Perl 6 development, new features are often made available for users to experimental with before their design is completed. Eventually these features may be made part of the Perl 6 specification. To use these features, one uses the experimental pragma in program source code, for example, like this:

use experimental :macros;

Following is a list of current experimental features and a short description of each feature's purpose or a link to more details about its use. (Note: Features marked "[TBD]" are to be defined later.)

The following should be a table but formatting in tables is not yet rendered properly.

Collation

The collate and coll methods are no longer experimental. However, they are affected by the $*COLLATION, which configures the four collation levels. While the Primary, Secondary and Tertiary mean different things for different scripts, for the Latin script used in English they mostly correspond with Primary being Alphabetic, Secondary being Diacritics and Tertiary being Case.

In the example below you can see how when we disable tertiary collation which in Latin script generally is for case, and also disable quaternary which breaks any ties by checking the codepoint values of the strings, we get Same back for A and a:

use experimental :collation;
$*COLLATION.set(:quaternary(False), :tertiary(False));
say 'a' coll 'A'; #OUTPUT: «Same␤»
say ('a','A').collate == ('A','a').collate; # OUTPUT: «True␤»

The $*COLLATION API could change at any time, so use it with caution.

18 FAQ

Frequently asked questions about Perl 6

General

What's the difference between Rakudo and Perl 6?

Properly speaking, Rakudo is an implementation of Perl 6. It's currently the most developed, but there have been other implementations in the past and there will likely be others in the future. Perl 6 is the definition of the language. Often, Rakudo and Perl 6 will be used interchangeably.

Has Perl 6 been released?

Yes with the Rakudo 2015.12 implementation version on December 25th 2015.

Is there a Perl 6 version 6.0.0?

No. The first stable language specification version is v6.c ("Christmas"). Future versions of the spec may have point releases (e.g. v6.c.2) or major releases (e.g., v6.d).

Running perl6 -v will display the language version your compiler implements:

$ perl6 -v 
 This is Rakudo version 2017.07 built on MoarVM version 2017.07 
 implementing Perl 6.c. 

When is v6.d going to be released?

There is no planned date, although Diwali 2018 looks to be an attractive date for a release codenamed Diwali.

The vast majority of 6.d features are already implemented and available in in the Rakudo compiler without requiring any special pragmas, as they did not conflict with the 6.c specification. A smaller set of features and behaviours is available automatically if you have the use v6.d.PREVIEW pragma at the top of the file. The rest of about 3100 new commits to the language specificication simply clarify previously undefined behaviour.

As a Perl 6 user, what should I install?

Mac users can use the latest Rakudo Star DMG binary installer at http://rakudo.org/downloads/star

Windows users can use the Rakudo Star MSI binary installer. You will need Windows Git and Strawberry Perl 5 to use zef to install library modules.

Linux users probably want to download Rakudo Star and follow the compilation instructions at http://www.perl6.org/downloads/.

There should be Linux and Mac binaries available from vendors and third parties, although vendor versions may be outdated. Versions before Rakudo release of 2015.12 should be avoided.

There's an official Rakudo Star docker image at https://hub.docker.com/_/rakudo-star/

As an advanced user I want to track Rakudo development.

An option is to clone the repository and build it. This will install work in progress which is minimally-tested and may contain severe bugs. If you're interested in contributing to Rakudo Perl 6 compiler, you may find Z-Script helper tool useful.

To install the last official monthly release check out the tag visible at https://raw.githubusercontent.com/rakudo/rakudo/master/VERSION or set up a helper command.

Some users choose to use rakudobrew, which allows installation of multiple versions of rakudo. Be sure to read its documentation.

In either case you will probably need to also install zef and p6doc from the ecosystem.

Where can I find good documentation on Perl 6?

See the official documentation website (especially its "Language" section) as well as the Resources page. You can also consult this great cheatsheet.

perl6book.com contains a list of dead tree and electronic books.

Be mindful of publication dates when reading third-party articles. Anything published before December, 2015 likely describes pre-release version of Perl 6.

You can always get help from a live human in our help chat or search the chat logs.

Can I get some books about Perl 6?

Here are some available books, in no particular order:

What is the Perl 6 specification?

The specification refers to the official test suite for Perl 6. It's called roast and is hosted on github. Any compiler that passes the tests is deemed to implement that version of the Perl 6 specification.

Roast's "master" branch corresponds to the latest development that isn't necessarily part of any specification yet. Other branches correspond to specific versions; for example, "6.c-errata".

So 6.c-errata is a released language version we don't change other than to fix errors in tests (the "errata") whereas master is the unreleased work-in-progress that may become the next language version. Its current state is not necessarily prescriptive of the next language version's behavior since new additions will be reviewed for inclusion into the release.

Yes, see glossary.

I'm a Perl 5 programmer. Where is a list of differences between Perl 5 and Perl 6?

There are several Perl 5 to Perl 6 guides in the Language section of the documentation, most notable of which is the Overview.

I'm a Ruby programmer looking for quickstart type docs?

See the rb-nutshell guide.

Modules

Is there a CPAN (repository of third party library modules) for Perl 6?

Yes, it's the same CPAN as for Perl 5! The only difference is when using PAUSE to upload the module, you'd select Perl 6 as the target directory and the uploaded modules show up on modules.perl6.org instead of MetaCPAN. The App::Mi6 tool can simplify the uploading process. Latest versions of zef module installer automatically check for latest versions of a module on CPAN as well as our GitHub-based ecosystem.

Is there a perldoc (command line documentation viewer) for Perl 6?

Yes, it's called p6doc and is present in the ecosystem under that name. It comes bundled in with Rakudo Star but needs to be manually installed with zef if you are using a Rakudo monthly release.

Can I use Perl 5 modules from Perl 6?

Yes, with Inline::Perl5, which works well with most Perl 5 modules. It can even run Perl 5 Catalyst and DBI.

Can I use C and C++ from Perl 6?

Nativecall makes this particularly easy.

Nativecall can't find libfoo.so and I only have libfoo.so.1.2!

This is commonly seen on Debian-like systems. You need to install libfoo-dev package, to set a sym link for the missing file.

Where have all the traditional UNIX library functions gone?

It's fairly easy to use NativeCall to access them.

An ecosystem module POSIX is also available.

Does Rakudo have a core standard library?

Rakudo Star distribution does come with many useful modules.

Rakudo compiler-only release includes only a couple of the most basic modules.

Many more modules can be found in the ecosystem.

Is there something like B::Deparse/How can I get hold of the AST?

Use --target=optimize command line option to view the AST of your program, e.g., perl6 --target=optimize -e 'say "hi"'

The target optimize gives the AST after the static optimizer did its job, while target ast gives the AST before that step. To get the full list of available targets, run perl6 --stagestats -e ""

What is Precompilation?

When you load a module for the first time, Rakudo compiles it into bytecode, and both stores it on disk, and uses the compiled bytecode. On subsequent loads, Rakudo prefers to load the bytecode, because that tends to be significantly faster.

Can I have circular dependencies between modules?

No, you can't have circular dependencies, and you should get Circular module loading detected error if you try it.

Very likely you can accomplish what you are trying to do using roles. Instead of A.pm6 depending on B.pm6 and B.pm6 depending on A.pm6, you can have A-Role.pm6 and B-Role.pm6 and classes in A.pm6 and B.pm6 implement these roles respectively. Then you can depend on A-Role.pm6 and B-Role.pm6 without the need for the circular dependency.

One of the reasons why circular dependencies do not work in Perl 6 is one pass parsing. We have to know what A means when we parse B, and we have to know what B means when we parse A, which is clearly an infinite loop.

Note that Perl 6 has no “1 file = 1 class” limitation, and circular dependencies within a single compilation unit (e.g. file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.

Language Features

How can I dump Perl 6 data structures (like Perl 5 Data::Dumper and similar)?

Typical options are to use say routine that uses gist method that gives the "gist" of the object being dumped. More detailed output can be obtained by calling perl method that typically returns representation in EVAL-able code.

If you're using the rakudo implementation, you can use the rakudo-specific dd routine for dumping, whose output is similar to perl, but with more information.

Examples:

my $foo = %( foo => 'bar' ); 
 say $foo.perl;   # OUTPUT: «${:foo("bar")}␤» 
 say $foo;        # OUTPUT: «{foo => bar}␤» 
 
 # non-standard routine available in rakudo implementation: 
 dd $foo;         # OUTPUT: «Hash $foo = ${:foo("bar")}␤» 

There are also several ecosystem modules that provide more control over how data structures are dumped, including support for colored output in.

How can I get command line history in the Perl 6 prompt (REPL)?

Install Linenoise from the ecosystem.

An alternative for UNIX-like systems is to install rlwrap. This can be done on Debian-ish systems by running:

sudo apt-get install rlwrap 

Why is the Rakudo compiler so apologetic?

If SORRY! is present in the output the error is a compile time error otherwise it's runtime.

Example:

say 1/0;   # Attempt to divide 1 by zero using div 
sub foo( Int $a, Int $b ) {...} 
 foo(1)     # ===SORRY!=== Error while compiling ... 

What is (Any)?

Any is a top level class most objects inherit from. The Any type object is the default value on variables and parameters without an explicit type constraint, which means you'll likely see (Any) printed when you output a gist of a variable without any value, such as using say routine:

my $foo; 
 say $foo; # OUTPUT: «(Any)␤» 
 
 my Int $baz; 
 say $baz; # OUTPUT: «(Int)␤» 
 
 my $bar = 70; 
 say $bar; # OUTPUT: «70␤» 

To test whether a variable has any defined values, see DEFINITE and defined routines. Several other constructs exist that test for definiteness, such as with , orwith , and without statements, //, andthen, notandthen, and orelse operators, as well as type constraint smileys.

What is so?

so is a loose precedence operator that coerces to Bool.

It has the same semantics as the ? prefix operator, just like and is the low-precedence version of &&.

Example usage:

say so 1|2 == 2;    # OUTPUT: «True␤»

In this example, the result of the comparison (which is a Junction), is converted to Bool before being printed.

What are those :D and :U things in signatures?

In Perl 6, classes and other types are objects and pass type checks of their own type.

For example, if you declare a variable

my Int $x = 42;

then not only can you assign integers (that is, instances of class Int) to it, but the Int type object itself:

$x = Int 

If you want to exclude type objects, you can append the :D type smiley, which stands for "definite":

my Int:D $x = 42; 
 $x = Int; 
 
 # dies with: 
 # Type check failed in assignment to $x; 
 # expected Int:D but got Int 

Likewise, :U constrains to undefined values, that is, type objects.

To explicitly allow either type objects or instances, you can use :_.

What is the --> thing in the signature?

--> is a return constraint, either a type or a definite value.

Example of a type constraint:

sub divide-to-int( Int $a, Int $b --> Int ) {
        return ($a / $b).narrow;
}

divide-to-int(3, 2)
# Type check failed for return value; expected Int but got Rat

Example of a definite return value:

sub discard-random-number( --> 42 ) { rand }
say discard-random-number;
# OUTPUT: «42␤»

In this case, the final value is thrown away because the return value is already specified.

How can I extract the values from a Junction?

If you want to extract the values (eigenstates) from a Junction, you are probably doing something wrong and should be using a Set instead.

Junctions are meant as matchers, not for doing algebra with them.

If you want to do it anyway, you can abuse autothreading for that:

sub eigenstates(Mu $j) {
    my @states;
    -> Any $s { @states.push: $s }.($j);
    @states;
}

say eigenstates(1|2|3).join(', ');
# prints 1, 2, 3 or a permutation thereof

If Str is immutable, how does s/// work? If Int is immutable, how does $i++ work?

In Perl 6, values of many basic types are immutable, but the variables holding them are not. The s/// operator works on a variable, into which it puts a newly created string object. Likewise, $i++ works on the $i variable, not just on the value in it.

Knowing this, you would not try to change a literal string (e.g. like 'hello' ~~ s/h/H/;), but you might accidentally do something equivalent using map as follows.

my @foo = <hello world>.map: { s/h/H/ };

# dies with
# Cannot modify an immutable Str (hello)

my @bar = <hello world>».subst-mutate: 'h', 'H';

# dies with
# Cannot resolve caller subst-mutate(Str: Str, Str);
# the following candidates match the type but require
# mutable arguments: ...

Instead of modifying the original value in place, use a routine or operator that returns a new value:

my @foo = <hello world>.map: { S/h/H/ };  # ['Hello','world']
my @bar = <hello world>».subst: 'h', 'H'; # ['Hello','world']

See the documentation on containers for more information.

What's up with array references and automatic dereferencing? Do I need the @ sigil?

In Perl 6, nearly everything is a reference, so talking about taking references doesn't make much sense. Scalar variables can also contain arrays directly:

my @a = 1, 2, 3;
say @a;                 # OUTPUT: «[1 2 3]␤»
say @a.^name;           # OUTPUT: «Array␤»

my $scalar = @a;
say $scalar;            # OUTPUT: «[1 2 3]␤»
say $scalar.^name;      # OUTPUT: «Array␤»

The big difference is that arrays inside a scalar act as one value in list context, whereas arrays will be happily iterated over.

my @a = 1, 2, 3;
my $s = @a;

for @a { ... }          # loop body executed 3 times
for $s { ... }          # loop body executed only once

my @flat = flat @a, @a;
say @flat.elems;            # OUTPUT: «6␤»

my @nested = flat $s, $s;
say @nested.elems;          # OUTPUT: «2␤»

You can force list context with @( ... ) or by calling the .list method on an expression, and item context with $( ... ) or by calling the .item method on an expression.

Why sigils? Couldn't you do without them?

There are several reasons:

"Type Str does not support associative indexing."

You likely tried to mix string interpolation and key characters, like HTML tags:

my $foo = "abc";
say "$foo<html-tag>";

Perl 6 thinks $foo to be a Hash and <html-tag> to be a string literal hash key. Use a closure to help it to understand you.

my $foo = "abc";
say "{$foo}<html-tag>";

Does Perl 6 have coroutines? What about yield?

Perl 6 has no yield statement like Python does, but it does offer similar functionality through lazy lists. There are two popular ways to write routines that return lazy lists:

# first method, gather/take 
 my @values = gather while have_data() { 
     # do some computations 
     take some_data(); 
     # do more computations 
 } 
 
 # second method, use .map or similar method 
 # on a lazy list 
 my @squares = (1..*).map(-> \x { x² }); 

Why can't I initialize private attributes from the new method, and how can I fix this?

Code like

class A {
    has $!x;
    method show-x {
        say $!x;
    }
}
A.new(x => 5).show-x;

does not print 5. Private attributes are private, which means invisible to the outside. If the default constructor could initialize them, they would leak into the public API.

If you still want it to work, you can add a submethod BUILD that initializes them:

class B {
    has $!x;
    submethod BUILD(:$!x) { }
    method show-x {
        say $!x;
    }
}
B.new(x => 5).show-x;

BUILD is called by the default constructor (indirectly, see Object Construction for more details) with all the named arguments that the user passes to the constructor. :$!x is a named parameter with name x, and when called with a named argument of name x, its value is bound to the attribute $!x.

But don't do that. If the name is public, there is no downside to declaring it that way with $.x since the external view is readonly by default, and you can still access it internally with $!x.

How and why do say, put and print differ?

The most obvious difference is that say and put append a newline at the end of the output, and print does not.

But there's another difference: print and put converts its arguments to a string by calling the Str method on each item passed to, say uses the gist method instead. The gist method, which you can also create for your own classes, is intended to create a Str for human interpretation. So it is free to leave out information about the object deemed unimportant to understand the essence of the object.

Or phrased differently, $obj.Str gives a string representation, $obj.gist a short summary of that object suitable for fast recognition by a human, and $obj.perl gives a Perlish representation from which the object could be re-created.

Example: type objects, also known as "undefined values", stringify to an empty string and warn, whereas the gist method returns the name of the type between parentheses (to indicate there's nothing in that value except the type).

my Date $x;     # $x now contains the Date type object
print $x;       # empty string plus warning
say $x;         # OUTPUT: «(Date)␤»

If you like to show a debugging version of an object, it is probably better to use the rakudo-specific dd routine. It essentially does a $obj.perl and shows that on STDERR rather than STDOUT, so it won't interfere with any "normal" output of your program.

So, say is optimized for casual human interpretation, dd is optimized for casual debugging output and print and put are more generally suitable for producing output.

put is thus a hybrid of print and say; like print, it calls the Str method on the object. And like say, it adds a newline at the end of the output.

What's the difference between token and rule ?

regex, token and rule introduce regexes, but with slightly different semantics.

token implies the :ratchet or :r modifier, which prevents the rule from backtracking.

rule implies both the :ratchet and :sigspace (short :s) modifier, which means a rule doesn't backtrace, and it treats whitespace in the text of the regex as <.ws> calls (i.e., matches whitespace, which is optional except between two word characters). Whitespace at the start of the regex and at the start of each branch of an alternation is ignored.

regex declares a plain regex without any implied modifiers.

What's the difference between die and fail?

die throws an exception.

fail returns a Failure object. (If the caller has declared use fatal; in the calling lexical scope, fail throws an exception instead of returning.)

A Failure is an "unthrown" or "lazy" exception. It's an object that contains the exception, and throws the exception if you try to use the Failure as an ordinary object, or ignore it in sink context.

A Failure returns False from a defined check, and you can extract the exception with the exception method.

What's the difference between Pointer and OpaquePointer?

OpaquePointer is deprecated and has been replaced with Pointer.

You can have colonpairs in identifiers. What's the justification?

Identifiers can include colon pairs, which become part of their name. According to Larry Wall's answer to the issue, We already had the colon pair mechanism available, so it was a no-brainer to use that to extend any name that needs to be able to quote uniquefying but non-standard characters (or other information with a unique stringification to such characters).

How does most people enter Unicode characters?

It depends on the operating system, windowing environment and/or editors. This page on entering Unicode characters specifies how it is done in the most popular operating systems and editors.

Perl 6 Implementation

What Perl 6 Implementations are available?

Currently the best developed is Rakudo (using multiple Virtual Machine backends). Historic implementations include Niecza (.NET) and Pugs (Haskell). Others are listed at Perl 6 Compilers

What language is Rakudo written in?

A short answer is that Rakudo is written almost entirely in Perl 6. A more detailed answer is that Rakudo is written in a mixture of Perl 6 and NQP ("Not Quite Perl"). NQP is a lightweight Perl 6-like environment for virtual machines; it's designed to be a high-level way to create compilers and libraries for virtual machines (such as MoarVM and JVM) using Perl 6 syntax.

What language is NQP written in?

NQP is a mixture of (1) NQP code, (2) whatever language the underlying virtual machine is using, (3) some third-party C and Java libraries, and (4) some bootstrapping files created by earlier runs of the build process.

Is Perl 6 Lisp?

(not (not Nil))

Perl 6 Distribution

When will the next version of Rakudo Star be released?

A Rakudo Star release is produced usually quarterly. See rakudo.org About for more information.

Meta Questions and Advocacy

Why is Perl 6 called Perl?

… As opposed to some other name that didn't imply all the things that the higher number might indicate on other languages.

The short answer is that it was Larry's choice under Rule 1.

The community considers Perl 5 and Perl 6 sister languages - they have a lot in common, address many of the same problem spaces, but Perl 6 is not intended to replace Perl 5. In fact, both languages interoperate with each other.

When will Perl 6 be ready? Is it ready now?

Readiness of programming languages and their compilers is not a binary decision. As the language and the implementations evolve, they grow steadily more usable. Depending on your needs, Perl 6 and its compilers may or may not be ready for you.

That said, version 6.c (Christmas 2015) is the first official release of Perl 6 as a language, along with a validation suite and a compiler that passes it.

Why should I learn Perl 6? What's so great about it?

Perl 6 unifies many great ideas that aren't usually found in other programming languages. While several other languages offer some of these features, none of them offer all.

Please see the feature comparison matrix for an overview of implemented features.

Is Perl 6 fast enough for me?

That depends on what you are doing. Rakudo has been developed with the philosophy of "make it work right then make it work fast". It's fast for some things already but needs work for others. Since Perl 6 provides lots of clues to the JIT that other dynamic languages don't, we think we'll have a lot of headroom for performance improvements.

The following crude benchmarks, with all the usual caveats about such things, show that Perl 6 can be faster than Perl 5 for similar tasks if the big weaponry is included; at the same time, Perl 5 can be faster if only the bare bones are included. Similar situation can be observed when comparing Perl 6 to other languages.

Try it on your system. You may be pleasantly surprised!

Examples:

# Perl 6 version 
 use v6.c; 
 
 class Foo { has $.i is rw }; 
 
 for 1..1_000_000 -> $i { 
     my $obj = Foo.new; 
     $obj.i = $i; 
 } 
# Perl 5 version 
 package Foo; 
 use Moose; 
 
 has i => (is => 'rw'); 
 
 __PACKAGE__->meta->make_immutable; 
 
 for my $i (1..1_000_000) { 
     my $obj = Foo->new; 
     $obj->i($i); 
 } 
 
 1; 
 
 # Another Perl 5 version that offers bare-bones set of features 
 # compared to Moose/Perl 6's version but those are not needed in this 
 # specific, simple program anyway. 
 package Foo; 
 use Mojo::Base -base; 
 
 has 'i'; 
 
 for my $i (1..1_000_000) { 
     my $obj = Foo->new; 
     $obj->i($i); 
 } 
 
 1; 
# A perl program which works under both perl5 (with perl -Mbigint) 
 # and perl6 
 
 my ($prev, $current) = (1, 0); 
 
 for (0..100_000) { 
     ($prev, $current) = ($current, $prev + $current); 
 } 
 print $current; 

19 Functions

Functions and functional programming in Perl 6

Routines are one of the means Perl 6 has to reuse code. They come in several forms, most notably methods, which belong in classes and roles and are associated with an object; and functions (also called subroutines or subs, for short), which can be called independently of objects.

Subroutines default to lexical (my) scoping, and calls to them are generally resolved at compile time.

Subroutines can have a signature, also called parameter list, which specifies which, if any, arguments the signature expects. It can specify (or leave open) both the number and types of arguments, and the return value.

Introspection on subroutines is provided via Routine.

Defining/Creating/Using Functions

Subroutines

The basic way to create a subroutine is to use the sub declarator followed by an optional identifier:

sub my-func { say "Look ma, no args!" }
my-func;

The sub declarator returns a value of type Sub that can be stored in any container:

my &c = sub { say "Look ma, no name!" }
c;     # OUTPUT: «Look ma, no name!␤»

my Any:D $f = sub { say 'Still nameless...' }
$f();  # OUTPUT: «Still nameless...␤»

my Code \a = sub { say ‚raw containers don't implement postcircumfix:<( )>‘ };
a.();  # OUTPUT: «raw containers don't implement postcircumfix:<( )>␤»

The declarator sub will declare a new name in the current scope at compile time. As such any indirection has to be resolved at compile time:

constant aname = 'foo';
sub ::(aname) { say 'oi‽' };
foo;

This will become more useful once macros are added to Perl 6.

To have the subroutine take arguments, a signature goes between the subroutine's name and its body, in parentheses:

sub exclaim  ($phrase)  { 
     say $phrase  ~  "!!!!" 
 } 
 exclaim "Howdy, World"; 

By default, subroutines are lexically scoped. That is, sub foo {...} is the same as my sub foo {...} and is only defined within the current scope.

sub escape($str) { 
     # Puts a slash before non-alphanumeric characters 
     S:g[<-alpha -digit>] = "\\$/" given $str 
 } 
 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 
 
 { 
     sub escape($str) { 
         # Writes each non-alphanumeric character in its hexadecimal escape 
         S:g[<-alpha -digit>] = "\\x[{ $/.ord.base(16) }]" given $str 
     } 
 
     say escape 'foo#bar?' # OUTPUT: «foo\x[23]bar\x[3F]␤» 
 } 
 
 # Back to original escape function 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 

Subroutines don't have to be named. If unnamed, they're called anonymous subroutines.

say sub ($a, $b) { $a ** 2 + $b ** 2 }(3, 4) # OUTPUT: «25␤»

But in this case, it's often desirable to use the more succinct block syntax. Subroutines and blocks can be called in place, as in the example above.

say -> $a, $b { $a ** 2 + $b ** 2 }(3, 4)    # OUTPUT: «25␤»

Or even

say { $^a ** 2 + $^b ** 2 }(3, 4)            # OUTPUT: «25␤»

Blocks and Lambdas

Whenever you see something like { $_ + 42 }, -> $a, $b { $a ** $b }, or { $^text.indent($:spaces) }, that's Block syntax. It's used after every if, for, while, etc.

for 1, 2, 3, 4 -> $a, $b {
    say $a ~ $b;
}
# OUTPUT: «12␤34␤»

They can also be used on their own as anonymous blocks of code.

say { $^a ** 2 + $^b ** 2}(3, 4) # OUTPUT: «25␤»

For block syntax details, see the documentation for the Block type.

Signatures

The parameters that a function accepts are described in its signature.

sub format (Str $s)  { ... } 
 ->  $a, $b  { ... } 

Details about the syntax and use of signatures can be found in the documentation on the Signature class.

Automatic Signatures

If no signature is provided but either of the two automatic variables @_ or %_ are used in the function body, a signature with *@_ or *%_ will be generated. Both automatic variables can be used at the same time.

sub s { say @_, %_ };
say &s.signature # OUTPUT: «(*@_, *%_)␤»

Arguments

Arguments are supplied as a comma separated list. To disambiguate nested calls, use parentheses:

sub f(&c){ c() * 2 }; # call the function reference c with empty parameter list
sub g($p){ $p - 2 };
say(g(42), 45);       # pass only 42 to g()

When calling a function, positional arguments should be supplied in the same order as the function's signature. Named arguments may be supplied in any order, but it's considered good form to place named arguments after positional arguments. Inside the argument list of a function call, some special syntax is supported:

sub f(|c){};
f :named(35);     # A named argument (in "adverb" form)
f named => 35;    # Also a named argument
f :35named;       # A named argument using abbreviated adverb form
f 'named' => 35;  # Not a named argument, a Pair in a positional argument
my \c = <a b c>.Capture;
f |c;             # Merge the contents of Capture $c as if they were supplied

Arguments passed to a function are conceptually first collected in a Capture container. Details about the syntax and use of these containers can be found in the documentation on the Capture class.

When using named arguments, note that normal List "pair-chaining" allows one to skip commas between named arguments.

sub f(|c){};
f :dest</tmp/foo> :src</tmp/bar> :lines(512);
f :32x :50y :110z;   # This flavor of "adverb" works, too
f :a:b:c;            # The spaces are also optional.

Return values

Any Block or Routine will provide its last expression as a return value to the caller. If return or return-rw are called their parameter, if any, will become the return value. The default return value is Nil.

sub a { 42 };
sub b { say a };
b;
# OUTPUT: «42␤»

Multiple return values are returned as a list or by creating a Capture. Destructuring can be used to untangle multiple return values.

sub a { 42, 'answer' };
put a.perl;
# OUTPUT: «(42, "answer")␤»

my ($n, $s) = a;
put [$s, $n];
# OUTPUT: «answer 42␤»

sub b { <a b c>.Capture };
put b.perl;
# OUTPUT: «\("a", "b", "c")␤»

Return Type Constraints

Perl 6 has many ways to specify a function's return type:

sub foo(--> Int)      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() returns Int {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() of Int      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
my Int sub foo()      {}; say &foo.returns; # OUTPUT: «(Int)␤» 

Attempting to return values of another type will cause a compilation error.

sub foo() returns Int { "a"; }; foo; # Type check fails 

returns and of are equivalent, and both take only a Type since they are declaring a trait of the Callable. The last declaration is, in fact, a type declaration, which obviously can take only a type. -->, however, can take either undefined or definite values.

Note that Nil and Failure are exempt from return type constraints and can be returned from any routine, regardless of its constraint:

sub foo() returns Int { fail   }; foo; # Failure returned 
 sub bar() returns Int { return }; bar; # Nil returned 

Multi-dispatch

Perl 6 allows for writing several routines with the same name but different signatures. When the routine is called by name, the runtime environment determines the proper candidate and invokes it.

Each candidate is declared with the multi keyword. Dispatch happens depending on the number (arity), type and name of arguments. Consider the following example:

# version 1 
 multi happy-birthday( $name ) { 
     say "Happy Birthday $name !"; 
 } 
 
 # version 2 
 multi happy-birthday( $name, $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 } 
 
 # version 3 
 multi happy-birthday( :$name, :$age, :$title  = 'Mr' ) { 
     say "Happy {$age}th Birthday $title $name !"; 
 } 
 
 
 # calls version 1 (arity) 
 happy-birthday 'Larry';                        # OUTPUT: «Happy Birthday Larry !␤» 
 # calls version 2 (arity) 
 happy-birthday 'Luca', 40;                     # OUTPUT: «Happy 40th Birthday Luca !␤» 
 # calls version 3 
 # (named arguments win against arity) 
 happy-birthday( age => '50', name => 'John' ); # OUTPUT: «Happy 50th Birthday Mr John !␤» 
 # calls version 2 (arity) 
 happy-birthday( 'Jack', 25 );                  # OUTPUT: «Happy 25th Birthday Jack !␤» 
 

The first two versions of the happy-birthday sub differs only in the arity (number of arguments), while the third version uses named arguments and is chosen only when named arguments are used, even if the arity is the same of another multi candidate.

When two sub have the same arity, the type of the arguments drive the dispatch; when there are named arguments they drive the dispatch even when their type is the same as another candidate:

multi happy-birthday( Str $name, Int $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 } 
 
 multi happy-birthday( Str $name, Str $title ) { 
     say "Happy Birthday $title $name !"; 
 } 
 
 multi happy-birthday( Str :$name, Int :$age ) { 
     say "Happy Birthday $name, you turned $age !"; 
 } 
 
 happy-birthday 'Luca', 40;                 # OUTPUT: «Happy 40th Birthday Luca !␤» 
 happy-birthday 'Luca', 'Mr';               # OUTPUT: «Happy Birthday Mr Luca !␤» 
 happy-birthday age => 40, name => 'Luca';  # OUTPUT: «Happy Birthday Luca, you turned 40 !␤» 
 

Named parameters participate in the dispatch even if they are not provided in the call. Therefore a multi candidate with named parameters will be given precedence.

For more information about type constraints see the documentation for the Signature class.

multi as-json(Bool $d) { $d ?? 'true' !! 'false'; }
multi as-json(Real $d) { ~$d }
multi as-json(@d)      { sprintf '[%s]', @d.map(&as-json).join(', ') }

say as-json( True );                        # OUTPUT: «true␤»
say as-json( 10.3 );                        # OUTPUT: «10.3␤»
say as-json( [ True, 10.3, False, 24 ] );   # OUTPUT: «[true, 10.3, false, 24]␤»

multi without any specific routine type always defaults to a sub, but you can use it on methods as well. The candidates are all the multi methods of the object:

class Congrats {
    multi method congratulate($reason, $name) {
        say "Hooray for your $reason, $name";
    }
}

role BirthdayCongrats {
    multi method congratulate('birthday', $name) {
        say "Happy birthday, $name";
    }
    multi method congratulate('birthday', $name, $age) {
        say "Happy {$age}th birthday, $name";
    }
}

my $congrats = Congrats.new does BirthdayCongrats;

$congrats.congratulate('promotion','Cindy'); # OUTPUT: «Hooray for your promotion, Cindy␤»
$congrats.congratulate('birthday','Bob');    # OUTPUT: «Happy birthday, Bob␤»

Unlike sub, if you use named parameters with multi methods, the parameters must be required parameters to behave as expected.

Please note that a non-multi sub or operator will hide multi candidates of the same name in any parent scope or child scope. The same is true for imported non-multi candidates.

proto

proto is a way to formally declare commonalities between multi candidates. It acts as a wrapper that can validate but not modify arguments. Consider this basic example:

proto congratulate(Str $reason, Str $name, |) {*}
multi congratulate($reason, $name) {
   say "Hooray for your $reason, $name";
}
multi congratulate($reason, $name, Int $rank) {
   say "Hooray for your $reason, $name -- got rank $rank!";
}

congratulate('being a cool number', 'Fred');     # OK
congratulate('being a cool number', 'Fred', 42); # OK
congratulate('being a cool number', 42);         # Proto match error 

The proto insists that all multi congratulate subs conform to the basic signature of two strings, optionally followed by further parameters. The | is an un-named Capture parameter, and allows a multi to take additional arguments. The first two calls succeed, but the third fails (at compile time) because 42 doesn't match Str.

say &congratulate.signature # OUTPUT: «(Str $reason, Str $name, | is raw)␤» 

You can give the proto a function body, and place the {*} where you want the dispatch to be done.

# attempts to notify someone -- False if unsuccessful
proto notify(Str $user,Str $msg) {
   my \hour = DateTime.now.hour;
   if hour > 8 or hour < 22 {
      return {*};
   } else {
      # we can't notify someone when they might be sleeping
      return False;
   }
}

{*} always dispatches to candidates with the parameters it's called with. Parameter defaults and type coercions will work but are not passed on.

proto mistake-proto(Str() $str, Int $number = 42) {*} 
 multi mistake-proto($str, $number) { say $str.^name } 
 mistake-proto(7, 42);  # OUTPUT: «Int␤» -- not passed on 
mistake-proto('test'); # fails -- not passed on 

only

The only keyword preceding sub or method indicates that it will be the only function with that name that inhabits a given namespace.

only sub you () {"Can make all the world seem right"};

This will make other declarations in the same namespace, such as

sub you ( $can ) { "Make the darkness bright" }

fail with an exception of type X::Redeclaration. only is the default value for all subs; in the case above, not declaring the first subroutine as only will yield exactly the same error; however, nothing prevents future developers from declaring a proto and preceding the names with multi. Using only before a routine is a defensive programming feature that declares the intention of not having routines with the same name declared in the same namespace in the future.

(exit code 1) 
 ===SORRY!=== Error while compiling /tmp/hDM1N2OAOo 
 Redeclaration of routine 'you' (did you mean to declare a multi-sub?) 
 at /tmp/hDM1N2OAOo:1 
 ------> ( $can ) { "Make the darkness bright" }⏏<EOL> 

Anonymous sub cannot be declared only. only sub {}' will throw an error of type, surprisingly, X::Anon::Multi.

Conventions and Idioms

While the dispatch system described above provides a lot of flexibility, there are some conventions that most internal functions, and those in many modules, will follow.

Slurpy Conventions

Perhaps the most important one of these conventions is the way slurpy list arguments are handled. Most of the time, functions will not automatically flatten slurpy lists. The rare exceptions are those functions that don't have a reasonable behavior on lists of lists (e.g., chrs) or where there is a conflict with an established idiom (e.g., pop being the inverse of push).

If you wish to match this look and feel, any Iterable argument must be broken out element-by-element using a **@ slurpy, with two nuances:

This can be achieved by using a slurpy with a + or +@ instead of **:

sub grab(+@a) { "grab $_".say for @a }

which is shorthand for something very close to:

multi sub grab(**@a) { "grab $_".say for @a }
multi sub grab(\a) {
    a ~~ Iterable and a.VAR !~~ Scalar ?? nextwith(|a) !! nextwith(a,)
}

This results in the following behavior, which is known as the "single argument rule" and is important to understand when invoking slurpy functions:

grab(1, 2);      # OUTPUT: «grab 1␤grab 2␤» 
 grab((1, 2));    # OUTPUT: «grab 1␤grab 2␤» 
 grab($(1, 2));   # OUTPUT: «grab 1 2␤» 
 grab((1, 2), 3); # OUTPUT: «grab 1 2␤grab 3␤» 

This also makes user-requested flattening feel consistent whether there is one sublist, or many:

grab(flat (1, 2), (3, 4));   # OUTPUT: «grab 1␤grab 2␤grab 3␤grab 4␤» 
 grab(flat $(1, 2), $(3, 4)); # OUTPUT: «grab 1 2␤grab 3 4␤» 
 grab(flat (1, 2));           # OUTPUT: «grab 1␤grab 2␤» 
 grab(flat $(1, 2));          # OUTPUT: «grab 1␤grab 2␤» 

It's worth noting that mixing binding and sigilless variables in these cases requires a bit of finesse, because there is no Scalar intermediary used during binding.

my $a = (1, 2);  # Normal assignment, equivalent to $(1, 2) 
 grab($a);        # OUTPUT: «grab 1 2␤» 
 my $b := (1, 2); # Binding, $b links directly to a bare (1, 2) 
 grab($b);        # OUTPUT: «grab 1␤grab 2␤» 
 my \c = (1, 2);  # Sigilless variables always bind, even with '=' 
 grab(c);         # OUTPUT: «grab 1␤grab 2␤» 

Functions are First-Class Objects

Functions and other code objects can be passed around as values, just like any other object.

There are several ways to get hold of a code object. You can assign it to a variable at the point of declaration:

my $square = sub (Numeric $x) { $x * $x }
# and then use it:
say $square(6);    # OUTPUT: «36␤»

Or you can reference an existing named function by using the &-sigil in front of it.

sub square($x) { $x * $x };

# get hold of a reference to the function:
my $func = &square

This is very useful for higher order functions, that is, functions that take other functions as input. A simple one is map, which applies a function to each input element:

sub square($x) { $x * $x };
my @squared = map &square,  1..5;
say join ', ', @squared;        # OUTPUT: «1, 4, 9, 16, 25␤»

Infix Form

To call a subroutine with 2 arguments like an infix operator, use a subroutine reference surrounded by [ and ].

sub plus { $^a + $^b };
say 21 [&plus] 21;
# OUTPUT: «42␤»

Closures

All code objects in Perl 6 are closures, which means they can reference lexical variables from an outer scope.

sub generate-sub($x) {
    my $y = 2 * $x;
    return sub { say $y };
    #      ^^^^^^^^^^^^^^  inner sub, uses $y
}
my $generated = generate-sub(21);
$generated(); # OUTPUT: «42␤»

Here, $y is a lexical variable inside generate-sub, and the inner subroutine that is returned uses it. By the time that the inner sub is called, generate-sub has already exited. Yet the inner sub can still use $y, because it closed over the variable.

Another closure example is the use of map to multiply a list of numbers:

my $multiply-by = 5;
say join ', ', map { $_ * $multiply-by }, 1..5;     # OUTPUT: «5, 10, 15, 20, 25␤»

Here, the block passed to map references the variable $multiply-by from the outer scope, making the block a closure.

Languages without closures cannot easily provide higher-order functions that are as easy to use and powerful as map.

Routines

Routines are code objects that conform to type Routine, most notably Sub, Method, Regex and Submethod.

They carry extra functionality in addition to what Block supplies: they can come as multis, you can wrap them, and exit early with return:

my $keywords = set <if for unless while>;

sub has-keyword(*@words) {
    for @words -> $word {
        return True if $word (elem) $keywords;
    }
    False;
}

say has-keyword 'not', 'one', 'here';       # OUTPUT: «False␤»
say has-keyword 'but', 'here', 'for';       # OUTPUT: «True␤»

Here, return doesn't just leave the block inside which it was called, but the whole routine. In general, blocks are transparent to return, they attach to the outermost routine.

Routines can be inlined and as such provide an obstacle for wrapping. Use the pragma use soft; to prevent inlining to allow wrapping at runtime.

sub testee(Int $i, Str $s){
    rand.Rat * $i ~ $s;
}

sub wrap-to-debug(&c){
    say "wrapping {&c.name} with arguments {&c.signature.perl}";
    &c.wrap: sub (|args){
        note "calling {&c.name} with {args.gist}";
        my \ret-val := callwith(|args);
        note "returned from {&c.name} with return value {ret-val.perl}";
        ret-val
    }
}

my $testee-handler = wrap-to-debug(&testee);
# OUTPUT: «wrapping testee with arguments :(Int $i, Str $s)»

say testee(10, "ten");
# OUTPUT: «calling testee with \(10, "ten")␤returned from testee with return value "6.151190ten"␤6.151190ten»
&testee.unwrap($testee-handler);
say testee(10, "ten");
# OUTPUT: «6.151190ten␤»
Important ones: candidates, wrap, unwrap, assuming, arity, count

Defining Operators

Operators are just subroutines with funny names. The funny names are composed of the category name (infix, prefix, postfix, circumfix, postcircumfix), followed by a colon, and a list of the operator name or names (two components in the case of circumfix and postcircumfix).

This works both for adding multi candidates to existing operators and for defining new ones. In the latter case, the definition of the new subroutine automatically installs the new operator into the grammar, but only in the current lexical scope. Importing an operator via use or import also makes it available.

# adding a multi candidate to an existing operator: 
 multi infix:<+>(Int $x, "same") { 2 * $x }; 
 say 21 + "same";            # OUTPUT: «42␤» 
 
 # defining a new operator 
 sub postfix:<!>(Int $x where { $x >= 0 }) { [*] 1..$x }; 
 say 6!;                     # OUTPUT: «720␤» 

The operator declaration becomes available as soon as possible, so you can recurse into a just-defined operator:

sub postfix:<!>(Int $x where { $x >= 0 }) { 
     $x == 0 ?? 1 !! $x * ($x - 1)! 
 } 
 say 6!;                     # OUTPUT: «720␤» 

Circumfix and postcircumfix operators are made of two delimiters, one opening and one closing.

sub circumfix:<START END>(*@elems) { 
     "start", @elems, "end" 
 } 
 
 say START 'a', 'b', 'c' END;        # OUTPUT: «(start [a b c] end)␤» 

Postcircumfixes also receive the term after which they are parsed as an argument:

sub postcircumfix:<!! !!>($left, $inside) { 
     "$left -> ( $inside )" 
 } 
 say 42!! 1 !!;      # OUTPUT: «42 -> ( 1 )␤» 

Blocks can be assigned directly to operator names. Use a variable declarator and prefix the operator name with a &-sigil.

my &infix:<ieq> = -> |l { [eq] l>>.fc };
say "abc" ieq "Abc";
# OUTPUT: «True␤»

Precedence

Operator precedence in Perl 6 is specified relatively to existing operators. The traits is tighter, is equiv and is looser can be provided with an operator to indicate how the precedence of the new operators is related to other, existing ones. More than one trait can be applied.

For example, infix:<*> has a tighter precedence than infix:<+>, and squeezing one in between works like this:

sub infix:<!!>($a, $b) is tighter(&infix:<+>) { 
     2 * ($a + $b) 
 } 
 
 say 1 + 2 * 3 !! 4;     # OUTPUT: «21␤» 

Here, the 1 + 2 * 3 !! 4 is parsed as 1 + ((2 * 3) !! 4), because the precedence of the new !! operator is between that of + and *.

The same effect could have been achieved with:

sub infix:<!!>($a, $b) is looser(&infix:<*>) { ... }

To put a new operator on the same precedence level as an existing operator, use is equiv(&other-operator) instead.

Associativity

When the same operator appears several times in a row, there are multiple possible interpretations. For example:

1 + 2 + 3

could be parsed as

(1 + 2) + 3         # left associative

or as

1 + (2 + 3)         # right associative

For addition of real numbers, the distinction is somewhat moot, because + is mathematically associative.

But for other operators it matters a great deal. For example, for the exponentiation/power operator, infix:<**> :

say 2 ** (2 ** 3);      # OUTPUT: «256␤»
say (2 ** 2) ** 3;      # OUTPUT: «64␤»

Perl 6 has the following possible associativity configurations:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
N non ILLEGAL
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

You can specify the associativity of an operator with the is assoc trait, where left is the default associativity.

sub infix:<§>(*@a) is assoc<list> { 
     '(' ~ @a.join('|') ~ ')'; 
 } 
 
 say 1 § 2 § 3;      # OUTPUT: «(1|2|3)␤» 

Traits

Traits are subroutines that run at compile time and modify the behavior of a type, variable, routine, attribute, or other language object.

Examples of traits are:

class ChildClass is ParentClass { ... } 
 #                ^^ trait, with argument ParentClass 
 has $.attrib is rw; 
 #            ^^^^^  trait with name 'rw' 
 class SomeClass does AnotherRole { ... } 
 #               ^^^^ trait 
 has $!another-attribute handles <close>; 
 #                       ^^^^^^^ trait 

... and also is tighter, is looser, is equiv and is assoc from the previous section.

Traits are subs declared in the form trait_mod<VERB> , where VERB stands for the name like is, does or handles. It receives the modified thing as argument, and the name as a named argument. See Sub for details.

multi sub trait_mod:<is>(Routine $r, :$doubles!) { 
     $r.wrap({ 
         2 * callsame; 
     }); 
 } 
 
 sub square($x) is doubles { 
     $x * $x; 
 } 
 
 say square 3;       # OUTPUT: «18␤» 

See type Routine for the documentation of built-in routine traits.

Re-dispatching

There are cases in which a routine might want to call the next method from a chain. This chain could be a list of parent classes in a class hierarchy, or it could be less specific multi candidates from a multi dispatch, or it could be the inner routine from a wrap.

Fortunately, we have a series of re-dispatching tools that help us to make it easy.

sub callsame

callsame calls the next matching candidate with the same arguments that were used for the current candidate and returns that candidate's return value.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callsame; 
     say "Back in Int with $res"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 1␤Back in Int with 5␤» 

sub callwith

callwith calls the next candidate matching the original signature, that is, the next function that could possibly be used with the arguments provided by users and returns that candidate's return value.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callwith($x + 1); 
     say "Back in Int with $res"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 2␤Back in Int with 5␤» 

Here, a 1 calls the most specific Int candidate first, and callwith re-dispatches to the less specific Any candidate. Note that although our parameter $x + 1 is an Int, still we call the next candidate in the chain.

In this case, for example:

proto how-many(|) {*} 
 
 multi how-many( Associative $a ) { 
     say "Associative $a "; 
     my $calling = callwith( 1 => $a ); 
     return $calling; 
 } 
 
 multi how-many( Pair $a ) { 
     say "Pair $a "; 
     return "There is $a " 
 
 } 
 
 multi how-many( Hash $a ) { 
     say "Hash $a"; 
     return "Hashing $a"; 
 } 
 
 my $little-piggie = little => 'piggie'; 
 say $little-piggie.^name;        # OUTPUT: «Pair␤» 
 say &how-many.cando( \( $little-piggie )); 
 # OUTPUT: «(sub how-many (Pair $a) { #`(Sub|68970512) ... } sub how-many (Associative $a) { #`(Sub|68970664) ... })␤» 
 say how-many( $little-piggie  ); # OUTPUT: «Pair little     piggie␤There is little piggie␤» 

the only candidates that take the Pair argument supplied by the user are the two functions defined first. Although a Pair can be easily coerced to a Hash, here is how signatures match:

say :( Pair ) ~~ :( Associative ); # OUTPUT: «True␤» 
 say :( Pair ) ~~ :( Hash );        # OUTPUT: «False␤» 

The arguments provided by us are a Pair. It does not match a Hash, so the corresponding function is thus not included in the list of candidates, as can be seen by the output of &how-many.cando( \( $little-piggie ));.

sub nextsame

nextsame calls the next matching candidate with the same arguments that were used for the current candidate and never returns.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     nextsame; 
     say "never executed because nextsame doesn't return"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 1␤» 

sub nextwith

nextwith calls the next matching candidate with arguments provided by users and never returns.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     nextwith($x + 1); 
     say "never executed because nextsame doesn't return"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 2␤» 

sub samewith

samewith calls current candidate again with arguments provided by users and returns return value of the new instance of current candidate.

proto a(|) {*} 
 
 multi a(Int $x) { 
   return 1 unless $x > 1; 
   return $x * samewith($x-1); 
 } 
 
 say (a 10); # OUTPUT: «36288002␤» 

sub nextcallee

Redispatch may be required to call a block that is not the current scope what provides nextsame and friends with the problem to referring to the wrong scope. Use nextcallee to capture the right candidate and call it at the desired time.

proto pick-winner(|) {*} 
 
 multi pick-winner (Int \s) { 
     my &nextone = nextcallee; 
     Promise.in(π²).then: { nextone s } 
 } 
 multi pick-winner { say "Woot! $^w won" } 
 
 with pick-winner ^5 .pick -> \result { 
     say "And the winner is..."; 
     await result; 
 } 
 
 # OUTPUT: 
 # And the winner is... 
 # Woot! 3 won 

The Int candidate takes the nextcallee and then fires up a Promise to be executed in parallel, after some timeout, and then returns. We can't use nextsame here, because it'd be trying to nextsame the Promise's block instead of our original routine.

wrapped routines

Besides those are mentioned above, re-dispatch is helpful in more situations. One is for dispatching to wrapped routines:

# enable wrapping: 
 use soft; 
 
 # function to be wrapped: 
 sub square-root($x) { $x.sqrt } 
 
 &square-root.wrap(sub ($num) { 
    nextsame if $num >= 0; 
    1i * callwith(abs($num)); 
 }); 
 
 say square-root(4);     # OUTPUT: «2␤» 
 say square-root(-4);    # OUTPUT: «0+2i␤» 

routines of parent class

Another use case is to re-dispatch to methods from parent classes.

class LoggedVersion is Version { 
     method new(|c) { 
         note "New version object created with arguments " ~ c.perl; 
         nextsame; 
     } 
 } 
 
 say LoggedVersion.new('1.0.2'); 

Coercion Types

Coercion types force a specific type for routine arguments while allowing the routine itself to accept a wider input. When invoked, the arguments are narrowed automatically to the stricter type, and therefore within the routine the arguments have always the desired type.

In the case the arguments cannot be converted to the stricter type, a Type Check error is thrown.

sub double(Int(Cool) $x) { 
     2 * $x 
 } 
 
 say double '21';    # OUTPUT: «42␤» 
 say double  21;     # OUTPUT: «42␤» 
 say double Any;     # Type check failed in binding $x; expected 'Cool' but got 'Any' 

In the above example, the Int is the target type to which the argument $x will be coerced, and Cool is the type that the routine accepts as wider input.

If the accepted wider input type is Any, it is possible to abbreviate the coercion Int(Any) omitting the Any type, thus resulting in Int().

The coercion works by looking for a method with the same name as the target type: if such method is found on the argument, it is invoked to convert the latter to the expected narrow type. From the above, it is clear that it is possible to provide coercion among user types just providing the required methods:

class Bar { 
    has $.msg; 
 } 
 
 class Foo { 
    has $.msg = "I'm a foo!"; 
 
    # allows coercion from Foo to Bar 
    method Bar { 
        Bar.new(:msg($.msg ~ ' But I am now Bar.')); 
    } 
 } 
 
 # wants a Bar, but accepts Any 
 sub print-bar(Bar() $bar) { 
    say $bar.^name; # OUTPUT: «Bar␤» 
    say $bar.msg;   # OUTPUT: «I'm a foo! But I am now Bar.␤» 
 } 
 
 print-bar Foo.new; 

In the above code, once a Foo instance is passed as argument to print-bar, the Foo.Bar method is called and the result is placed into $bar.

Coercion types are supposed to work wherever types work, but Rakudo currently (2018.05) only implements them in signatures, for both parameters and return types.

Non-parameter coercion types will theoretically be working in 6.2. Updated the reference above to latest version.

Coercion also works with return types:

sub are-equal (Int $x, Int $y --> Bool(Int) ) { $x - $y }; 
 
 for (2,4) X (1,2) -> ($a,$b) { 
     say "Are $a and $b equal? ", are-equal($a, $b); 
 } #  OUTPUT: «Are 2 and 1 equal? True␤Are 2 and 2 equal? False␤Are 4 and 1 equal? True␤Are 4 and 2 equal? True␤» 

In this case, we are coercing an Int to a Bool, which is then printed (put into a string context) in the for loop that calls the function.

sub MAIN

The sub with the special name MAIN is executed after all relevant phasers. Its signature is the means by which command line arguments can be parsed. Multi methods are supported and a usage method is automatically generated and displayed if no command line arguments are provided. All command line arguments are also available in @*ARGS, which can be mutated before being processed by MAIN.

Unlike other ordinary functions, any return value provided by MAIN will be ignored by the invoker, even if explicitly set by means of a return statement (that will terminate the MAIN function). The default return code of MAIN is always zero (0, success). In order to provide any return value different from zero, a call to exit has to be performed.

#|(optional description for USAGE message)
sub MAIN( Int :$length = 24,
           :file($data) where { .IO.f // die "file not found in $*CWD" } = 'file.dat',
           Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) )
{
    say $length if $length.defined;
    say $data   if $data.defined;
    say 'Verbosity ', ($verbose ?? 'on' !! 'off');

    exit 1;
}

This MAIN is defining two kind of aliases, as explained in Signatures: :file($data) aliases the content passed to the command-line parameter --file= to the variable $data; :v(:$verbose) not only aliases v to verbose, but also creates a new command line parameter verbose thanks to the specification of the :. In fact, since this is an alias, both verbose and v can use single or double dashes (- or --).

With file.dat present, this will work this way

$ perl6 Main.p6 
 24 
 file.dat 
 Verbosity off 

Or this way with -v or --verbose

$ perl6 Main.p6 -v 
 24 
 file.dat 
 Verbosity on 

%*SUB-MAIN-OPTS

It's possible to alter how arguments are processed before they're passed to sub MAIN {} by setting options in %*SUB-MAIN-OPTS hash. Due to the nature of dynamic variables, it is required to set up %*SUB-MAIN-OPTS hash and fill it with the appropriate settings. For instance:

my %*SUB-MAIN-OPTS =
  :named-anywhere,    # allow named variables at any location
  :!foo,              # don't allow foo
;
sub MAIN ($a, $b, :$c, :$d) {
    say "Accepted!"
}

Available options are:

named-anywhere

By default, named arguments passed to the program (i.e., MAIN) cannot appear after any positional argument. However, if %*SUB-MAIN-OPTS<named-anywhere> is set to a true value, named arguments can be specified anywhere, even after positional parameter. For example, the above program can be called with:

perl6 example.p6 1 --c=2 3 --d=4 

Unit-scoped definition of MAIN

If the entire program body resides within MAIN, you can use the unit declarator as follows:

unit sub MAIN( Int :$length = 24, 
                 :file($data) where { .IO.f // die "file not found in $*CWD" } = 'file.dat', 
                 Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) ); 
 
 # rest of script is part of MAIN 

Note that this is only appropriate if you do not need a proto or multi definition.

sub USAGE

If no multi candidate of MAIN is found for the given command line parameters, the sub USAGE is called. If no such method is found, the compiler will output a default generated usage message.

#|(is it the answer)
multi MAIN(Int $i) { say $i == 42 ?? 'answer' !! 'dunno' }
#|(divide two numbers)
multi MAIN($a, $b){ say $a/$b }

sub USAGE() {
print Q:c:to/EOH/;
Usage: {$*PROGRAM-NAME} [number]

Prints the answer or 'dunno'.
EOH
}

The default usage message is available inside sub USAGE via read-only $*USAGE variable. It will be generated based on available sub MAIN candidates and their parameters. You can specify additional extended description for each candidate using #|(...) Pod block to set WHY.

20 Glossary

Glossary of Perl 6 terminology

Abstract Class

The generic Computer Science term "abstract class" defines the interface or #API of a class. In Perl 6, this is implemented using roles with stubbed methods.

role Canine {
    method bark { ... }          # the ... indicates a stub
}

class Dog does Canine {
    method bark { say "woof" }   # *MUST* be implemented by class
}

Advent Calendar

In the context of Perl 6, a yearly set of blog posts for each day from the 1st until the 25th of December, to be found at https://perl6advent.wordpress.com.

Adverb

Generically, an adverb is a named argument to a function. There are also some specific syntax forms that allow adverbs to be tucked into some convenient places:

q:w"foo bar";   # ":w" is a Quotelike form modifier adverb
m:g/a|b|c/;     # ":g" is also
TODO: Add this back in when :rotate on infix operators is supported 4 +> 5 :rotate # ":rotate" is an operator adverb @h{3}:exists; # ":exists" is also, but is known as a subscript adverb

Adverbs are usually expressed with colon pair notation, and for this reason colon pair notation is also known as the adverbial pair form:

:a(4)          # Same as "a" => 4

Some other forms that use a colon in ways that have adverb-like semantics are called adverbial forms. One special form starts with an integer value, followed by a name (for the key):

:20seconds     # same as seconds => 20

Also see #Colon Pair and Colon List.

Adverbial Pair

A generalized form of pair notation. They all start with the colon, like:

adverbial pair pair notation
:foo<bar> foo => 'bar'
:foo(42) foo => 42
:42foo foo => 42
:$foo foo => $foo
:foo foo => True
:!foo foo => False

Also see #Adverb and #Colon Pair and Colon List.

Allomorph

A type that has two related values which may be used depending on the context. For example IntStr allomorph is both an Int and a Str, so it will be accepted by anything that expects an Int, a Str, or an IntStr. Keep in mind that certain constructs, such as sets, bags, and mixes care about object identity, and so will not accept an allomorph as equivalent of its components alone.

The allomorph types IntStr, NumStr, RatStr and ComplexStr may be created as a result of parsing a quoted string:

say <42>.^name;     # OUTPUT: «IntStr␤»
say <42.1e0>.^name; # OUTPUT: «NumStr␤»
say <42.1>.^name;   # OUTPUT: «RatStr␤»

Note: angle brackets can also be used to create literals for which you'd normally need to use some operator (e.g. / for Rat or + for Complex). This allows you to use such literals in places where expressions are not allowed, for example, as literals in signatures:

# Wrong, can't use an operator there: 
 multi foo (1/3) { say "It's one third!" } 
# Right, a Rat literal: 
 multi foo (<1/3>) { say "It's one third!" } 

If you do want an allomorph and not a literal Numeric, then include whitespace around angle brackets:

say <42/1>.^name;    # OUTPUT: «Rat␤»
say <42+0i>.^name;   # OUTPUT: «Complex␤»
say < 42+0i >.^name; # OUTPUT: «ComplexStr␤»
say < 42/1 >.^name;  # OUTPUT: «RatStr␤»

Please see the Numerics page for a more complete description on how to work with these allomorphs.

Anonymous

A subroutine, method or submethod is called anonymous if it can't be called by name.

# named subroutine
sub double($x) { 2 * $x };

# anonymous subroutine, stored in a named scalar
my $double = sub ($x) { 2 * $x };

Note that it is still allowed to have a name, but you cannot call it by that name:

# anonymous, but knows its own name 
 my $s = anon sub triple($x) { 3 * $x } 
 say $s.name;        # OUTPUT: «triple␤» 
say triple(42);     # OUTPUT: «Undeclared routine: triple␤» 

API

Application Programming Interface. Ideally, someone using your system or library should be able to do so with knowledge only of the API, but not necessarily knowing anything about the internals or implementation.

See also #Abstract Class.

Apocalypse

A document originally written by #TimToady, in which he processed the initial barrage of RFCs that came out of the Perl community. Now only kept as an historical document for reference. See also #Exegesis and #Synopsis.

Arity

The number of positional operands expected by an operator, subroutine, method or callable block.

sub infix:<+>(Foo $a, Foo $b) { $a.Int + $b.Int }  # arity of "+" is 2 
 sub frobnicate($x) { ... }                         # arity of 1 
 sub the-answer() { 42 }                            # arity of 0 
 -> $key, $value { ... }                            # arity of 2 

The arity of a Callable is one of the main selectors in multi-dispatch.

ASCII operator

“Texas” was used in the past but is now discouraged. Remove the link when “Texas” goes completely out of use.

The ASCII variant of a non-ASCII Unicode operator or symbol. For instance, (elem) corresponds to the ("Is this an element of that set?") operator that comes from set theory. ASCII operators are a workaround to the problem that people don't know how to type Unicode yet. Culturally, while we encourage people to use the Unicode symbols in a vague sort of way, we do not disparage the use of the ASCII variants. Well, maybe just a little...

Autothreading

Autothreading is what happens if you pass a Junction to a subroutine that expects a parameter of type Any or a subtype thereof (such as anything Cool). The call is then executed for each value of the junction. The result of these calls is assembled in a new junction of the same type as the original junction.

sub f($x) { 2 * $x };
say f(1|2|3) == 4;    # OUTPUT: «any(False, True, False)␤»

Here f() is a sub with one parameter, and since it has no explicit type, it is implicitly typed as Any. The Junction argument causes the f(1|2|3) call to be internally executed as f(1)|f(2)|f(3), and the resulting junction is 2|4|6. These are then all compared to 4, resulting in a junction False|True|False. This process of separating junction arguments into multiple calls to a function is called autothreading.

If you use the resulting junction in a boolean context, such as with an if, it collapses into a single boolean which is True if any of the values in the junction are True.

    if f(1|2|3) == 4 {    # fires because f(2) == 4 is true 
         say 'success'; 
     } 

Backtracking

Backtracking is the default way a regexp is matched. The engine is allowed to explore several ways moving backward in the string characters in order to allow every piece of a regexp to match something. For more information see Regexp Backtracking section.

binder

When you pass an argument list to a function (or any other callable, like a method or a block), the argument list gets bound to the parameters in the signature. The code that does this is called the binder.

block

Blocks are code object with its own lexical scope, which allows them to define variables without interfering with other in the containing block.

bytecode

Although Perl 6 looks like an interpreted language, since it uses the #! form to run its scripts (and they are called scripts), it is actually compiled to run in a virtual machine so the compiler (currently Rakudo) generates bytecode that runs either in MoarVM or the Java Virtual Machine, the two VMs currently supported.

Camelia

A butterfly image intended primarily to represent Perl 6, The Language.

Colon Pair and Colon List

A colon pair is a shorthand syntax used to create or visually present a Pair object. The two most common forms are:

:a(4)          # Same as "a" => 4,   same as Pair.new("a", 4)
:a<4>          # Same as "a" => "4", same as Pair.new("a", val("4"))

This is also known as the adverbial pair form. Note: when the part after the colon and before the brackets is not a legal identifier, other semantics apply, not all of which produce Pair objects.

Two other common forms are:

:a             # Same as :a(True)
:!a            # Same as :a(False)

A colon list just means that a list that contains only colon pairs, does not need commas, or even spaces:

:a(4):c:!d:c   # Same as a => 4, c => True, d => False, c => True

Finally, if there is a variable with the same name as an intended adverbial pair, you don't have to specify the name twice, but just specify the adverb with the appropriate sigil:

:$foo          # same as foo => $foo 
 :@bar          # same as bar => @bar 
 :%mapper       # same as mapper => %mapper 
 :&test         # same as test => &test 

See also #Adverb.

Community

See https://perl6.org/community/ for information about how to participate in the friendly Perl 6 community.

Damian Conway

Original author of the #Exegesis (among many other things). See also https://en.wikipedia.org/wiki/Damian_Conway.

diffy

See operator. It means the type of the operator result is sufficiently different from its arguments that op= makes little sense

Exegesis

A document originally written by #TheDamian, in which he tried to explain the Apocalypses to the common (wo)man. Now only kept as an historical document for reference. See also #Synopsis.

fiddly

Too complicated to apply a meta-op to. See operator.

Handle

A handle is a data structure used to store information about some input/output operation such as file or socket reading or writing. Perl 6 uses IO::Handle as a base class for filehandles, and IO::Socket for sockets.

Huffmanize

With reference to Huffman coding, "huffmanizing" is making things that are commonly used easier, and often shorter, to type. With things that are used less frequently it's both less of a bother to type longer pieces of code and often longer, more descriptive naming is necessary to easily be reminded of what the rarely-used feature does.

For example, printing output is a common task, while performing thread-safe atomic addition on native atomicity-safe integers is much less so. There's a need to "huffmanize" the task printing and that's why you can do it by just typing three letters put. But there's no need to "huffmanize" the rarely-needed atomic operators, which is why you type the lengthier names, such as atomic-inc-fetch. put is a bit of a vague name, but because it's commonly used, it's easy to learn what it does. atomic-inc-fetch, on the other hand is rarer, and the more descriptive name helps recall its purpose better.

iffy

Often used as a boolean value. See operator. Made via the use keyword.

import

Include functions from a module in the current namespace.

Instance

An instance of a class is also called an object in some other programming languages. It has storage for attributes and is often the return value of a call to a method called new, or a literal.

Instances of most types are defined to be True e.g., defined($instance) is True.

my Str $str = "hello";  ## this is with builtin types, e.g. Str
if defined($str) {
    say "Oh, yeah. I'm defined.";
}
else {
    say "No. Something off? ";
}

## if you wanted objects...
class A {
    # nothing here for now.
}

my $an_instance = A.new;
say $an_instance.defined.perl;# defined($an_instance) works too.

To put things another way, a class contains the blueprints of methods and attributes, and an instance carries it into the real world.

Interface

An interface is an abstract class.

Invocant

Caller, the one who calls or invokes. The invocant of a method would be the object on which that method is being called, or, in some cases, the class itself. Invocant is used instead of caller because the latter refers to the scope.

IRC

Internet Relay Chat. Perl 6 developers and users usually hang out on the #perl6 channel of irc.freenode.org. Currently available bots are:

camelia

The #Bot on the #perl6 #IRC channel that evaluates code, e.g.:

[16:28:27]  <lizmat>  m: say "Hello world" 
 [16:28:28]  <+camelia>    rakudo-moar 812a48: OUTPUT«Hello world␤» 

This is a handy tool for showing people if the output is (un)expected.

dalek

The #Bot on the #perl6 #IRC channel that reports changes made to various Perl 6 related repositories.

[15:46:40] <+dalek> doc: 2819f25 | lizmat++ | doc/Language/glossary.pod: 
 [15:46:40] <+dalek> doc: Add stubs for stuff inside the glossary already 
 [15:46:40] <+dalek> doc: review: https://github.com/perl6/doc/commit/2819f250 

yoleaux

The #Bot on the #perl6 #IRC channel that provides various services to people logged in. Commands to yoleaux (a pun on YOLO) start with a period. Some often used commands are:

.tell

Leave a message to another user who is currently not logged in. The message will be relayed as soon as the user says anything on the channel.

.tell lizmat I've read the glossary 

.u

Look up unicode codepoint information from either a codepoint, or the name of a codepoint.

[16:35:44]  <lizmat>   .u empty set 
 [16:35:45]  <yoleaux>  U+2205 EMPTY SET [Sm] (∅) 
 [16:36:29]  <lizmat>   .u ∅ 
 [16:36:30]  <yoleaux>  U+2205 EMPTY SET [Sm] (∅) 

Some #IRC clients then easily allow you to copy/paste the codepoint in question, which can be sometimes be easier than other unicode codepoint input methods.

IRC Lingo

The following terms are often used on the Perl 6 related #IRC channels:

ALAP

As Late As Possible

autopun

A self-referencing pun, e.g. "Are you ignorant or apathetic?" - "I don't know, and I don't care."

backlog

That part of a discussion on an #IRC channel that you've missed. If it is not or no longer available in your IRC client, you can go to sites such as http://colabti.org/irclogger/irclogger_logs/perl6 to see what has been logged for you.

Bot

A program that does automatic tasks on one or more #IRC channels by acting like a regular user (as far as the IRC server is concerned) and performing some tasks that may involve answering to users requests. Examples are #camelia, #dalek and #yoleaux.

Compilation unit or compunit

A compunit is a piece of Perl 6 code that is analyzed and compiled as a single unit. Typically, this piece of code will be contained in a single file, but code inside an EVAL is also considered a compunit.

DWIM

Do What I Mean. A programming language designer motto.

flap

Sometimes a test will fail under some conditions, but not others; when this test passes some test runs and fails others, it's called flapping.

fossil

Something in a generally current document that is no longer true but which has not yet been fixed by correcting or removing it.

FSVO

For Some Value Of...

FTFY

Fixed That For You

IIRC

If I Read (or Remember) Correctly

IMHO

In My Humble Opinion

IWBN

It Would Be Nice

LHF

Low Hanging Fruit. Usually used in the context of a (relatively) simple task to be performed by a (relative) newbie.

LGTM

Looks Good To Me

LTA

Less Than Awesome. Usually used in the context of an error message that is rather non-descriptive or unrelated to the actual error.

NST

No Such Thing

Opt

Short for "optimization", usually in either the context of spesh or JIT.

PB

Short for "problem". As in "that's not the pb".

PR

See #Pull Request.

P5

Perl 5

P6

Perl 6

RSN

Real Soon Now

RT

Request Tracker (http://rt.perl.org/). The place where all the bugs related to #Rakudo live.

TIMTOWTDI

An alternative form of #TMTOWTDI, explicitly including the "is" from the contraction "There's".

TMI

Too Much Information.

TMTOWTDI

"There's More Than One Way To Do It", the Perl motto.

UGT

"Universal Greeting Time" - i.e., it's always "morning".

WFM

Works For Me

WIP

Work In Progress

WP

Wikipedia

WW

Short for wrong window. When on #IRC, someone types something in a channel that was intended for another channel, or for a private message.

Larry Wall

Perl's benevolent dictator for life, among many other things. See also https://en.wikipedia.org/wiki/Larry_Wall.

Lexing

Performing lexical analysis. A step which usually precedes parsing.

Literal

A literal is a piece of code that directly stands for an (often built-in) object and also refers to the object itself.

my $x = 2;      # the 2 is a literal
say $x;         # $x is not a literal, but a variable
my $s = "Foo";  # the "Foo" is a literal, the $s is a variable

LHS

As an acronym left-hand side, it usually refers to the left hand side of an expression, and more specifically to the left-hand side of expressions such as $lhs = "this would be the right-hand side". Since the left hand side of these expressions modify their value, when something behaves as a LHS it means that it can be read and written to.

lvalue

An lvalue, or a left value, is anything that can appear on the left-hand side of the assignment operator =. It is anything you can assign to.

Typical lvalues are variables, private and is rw attributes, lists of variables and lvalue subroutines.

Examples of lvalues:

Declaration lvalue Comments
my $x; $x
my ($a, $b); ($a, $b)
has $!attribute; $!attribute Only inside classes
has $.attrib is rw; $.attrib
sub a is rw { $x }; a()

Examples of things that are not lvalues:

3 literals
constant x = 3; constants
has $.attrib; attributes; you can only assign to $!attrib
sub f { }; f(); "normal" subs are not writable
sub f($x) { $x = 3 }; error - parameters are read-only by default

These are typically called rvalues.

Mainline

The mainline is the program text that is not part of any kind of block.

use v6.c;     # mainline
sub f {
              # not in mainline, in sub f
}
f();          # in mainline again

You can also have the mainline of any package-like declarator, such as class, module, grammar, etc. These are typically run just after the class/module/grammar have been compiled (or when loaded from a pre-compiled file).

MoarVM

MoarVM is short for Metamodel On A Runtime Virtual Machine. It's a virtual machine designed specifically for #NQP and its MOP: #6model. A document about the purpose of MoarVM. MoarVM has some similarities with the Hotspot VM so you may peruse its glossary for entries missing from the present one.

Multi-Dispatch

The process of picking a candidate for calling of a set of methods or subs that come by the same name but with different arguments. The most narrow candidate wins. In case of an ambiguity, a routine with is default trait will be chosen if one exists, otherwise an exception is thrown.

multi-method

A method that has multiple candidates going by the same name and are subject to Multi-Dispatch.

NFG

Normal Form Grapheme is the way Perl 6 implements graphemes, using a normal form in which strings with the same graphemes can be easily compared in constant time. More on that on this article in 6guts and an explanation of how NFG works in this IRC log.

Niecza

An implementation of Perl 6 targeting the .NET platform. No longer actively maintained.

Not Quite Perl

See #NQP.

NQP

NQP is a primitive language for writing subroutines and methods using a subset of the Perl 6 syntax. It's not intended to be a full-fledged programming language, nor does it provide a runtime environment beyond the basic VM primitives. Compilers (such as #Rakudo) typically use NQP to compile action methods that convert a parse tree into its equivalent abstract syntax tree representation.

NYI

Not Yet Implemented

opcode

An opcode, or operation code, is a bytecode operation, that is, a command of the language actually used on the virtual machine. They are not usually intended for human consumption, but they are usually specified somewhere, like this document for MoarVM.

Operator

An expression is made of operators and operands. More precisely it is made of an operator and operands that can be subexpressions or #values. Operators are an alternative syntax for a #multi-method. With that syntax, what would be the arguments of the function are named operands instead. Operators are classified into categories of categories. A category has a precedence, an arity, and can be #fiddly, #iffy, #diffy. Perl 6 is very creative as to what is an operator, so there are many categories. Operators are made of many tokens, possibly with a subexpression. For example, @a[0] belongs to the postcircumfix category, is broken into the operand @a and the postcircumfix operator [0] where 0 is the postcircumfixed subexpression.

The <O(I<...>)> construction gives information about an operator that completes the information provided by its category. Below %conditional is the category, :reducecheck<ternary> , which specifies calling .ternary to post-process the parse subtree and :pasttype<if> specifies the NQP #opcode generated in the AST from the parse subtree.

<O('%conditional, :reducecheck<ternary>, :pasttype<if>')>

Parse Tree

A parse tree represents the structure of a string or sentence according to a grammar. Grammars in Perl 6 output parse trees when they successfully match a string.

Parameter

Parameter is a class to define parameters to subroutines, method and a callable blocks. As opposed to the arguments you specify when calling a subroutine/method/callable block.

sub foo($bar) { say $bar }     # $bar is a parameter
foo(42);                       # 42 is an argument

Parrot

A virtual machine designed to run Perl 6 and other dynamic languages. No longer actively maintained.

PAST

#Parrot AST.

Perl

The Perl programming language in its many forms.

PERL

A way to describe Perl as a language, considered to be improper by many in the Perl Community.

POD

Plain Ol' Documentation, a documentation format understood by Perl 6. See S26.

Pull request

A feature of GitHub and other git hosts like GitLab that allows you to make patches to be easily applied using the GitHub web user interface. It means you request someone to do a git pull from your repository to hers. PR is its usual acronym.

property

In this context, it either refers to an object property, which is the value of an instance variable, or an Unicode property which are codepoint features that allow programs to identify what kind of entity they represent, that is, if they are a letter, or a number, or something completely different like a control character.

pugs

pugs was one of the first interpreters/compilers written for Perl 6. It was written in Haskell by Audrey Tang.

p6y

Retronym for the "Perl 6 way" of doing things, as in idiomatic expressions or definitions. First known use with this meaning by sorear in the #perl6 IRC channel in 2010.

QAST

Successor to #PAST ('Q' being the next letter after 'P').

Rakudo

Rakudo is the name of a Perl 6 implementation that runs on #MoarVM and the JVM. It is an abbreviation of Rakuda-do, which, when translated from Japanese, means "The Way of the Camel". Also, in Japanese, "Rakudo" means "Paradise."

Reify

In the English language, reify means "to convert into or regard as a concrete thing." Its meaning in Perl 6 is very similar, in that conceptual things, like "elements of an infinite list", get reified when you try to operate on some of them.

Repository

A filesystem under control of a source control management application, usually git, that holds the sources for a project, library or application. This file, for instance, is in a GitHub repository. Repositories store not only files, but also history of changes and can be used by the developing or writing team for interaction through issues or comments to code.

In Perl 6 context, however, a repository is also a short name for compilation unit repository and constitutes a system that locates and loads modules, managing their installation and precompilation. They are structured as linked lists, including chain of repositories ending in the default Compunit::Repository::Installation.

RHS

Acronym for Right-Hand Side, usually refers to the right-hand side of assignment expressions such as my $bound := $rhs.

roast

The Perl 6 specification tests, which live here: https://github.com/perl6/roast/. Originally developed for #pugs, it now serves all Perl 6 implementations. Why roast? It's the repository of all spec tests.

Roles

Roles, mix-ins or traits define interfaces and/or implementation of those interfaces as well as instance variables using them, and are mixed-in when declaring classes that follow that interface. Abstract classes are particular examples of Roles where the actual implementation is deferred to the class that uses that Role.

Roles are part of Perl6's object system, and are declared using the keyword role and used in class declaration via does.

rule

(Used in regular expressions)

rvalue

A value that can be used on the right-hand side of an assignment. See also #lvalue.

Semilist

A semilist is a semicolon-separated list like this one: 1;3;5, and is actually a list of lists, with each component of the semilist being a slice of a particular dimension. @array[1;3;5] would be equivalent to @array[1][3][5].

Sigil

In Perl, the sigil is the first character of a variable name. It must be either $, @, %, or & respectively for a scalar, array, hash, or code variable. See also Twigil and role. Also sigiled variables allow short conventions for variable interpolation in a double quoted string, or even postcircumfix expressions starting with such a variable.

Sigilless Variable

Sigilless variables are actually aliases to the value it is assigned to them, since they are not containers. Once you assign a sigilless variable (using the escape \), its value cannot be changed.

Spesh

A functionality of the #MoarVM platform that uses runtime gathered data to improve commonly used pieces of #bytecode. It is much like a JIT compiler, except that those usually output machine code rather than bytecode.

STD

STD.pm is the "standard" Perl 6 grammar definition, see https://github.com/perl6/std/ that was used to implement Perl 6. STD.pm is no longer really a "specification" in a proscriptive sense: it's more of a guideline or model for Perl 6 implementations to follow.

Stub

Stubs define name and signature of methods whose implementation is deferred to other classes.

role Canine {
    method bark { ... }          # the ... indicates a stub
}

Classes with stubs are Abstract classes.

Symbol

Fancy alternative way to denote a name. Generally used in the context of modules linking, be it in the OS level, or at the Perl 6 #Virtual Machine level for modules generated from languages targeting these VMs. The set of imported or exported symbols is called the symbol table.

Synopsis

The current human-readable description of the Perl 6 language. Still in development. Much more a community effort than the Apocalypses and Exegeses were. The current state of the language is reflected by #roast, its #test suite, not the synopses where speculative material is not always so flagged or more recent additions have not been documented. This is even more true of material that has not been yet implemented.

Syntax Analysis

A syntax or syntactic analysis is equivalent to parsing a string to generate its Parse Tree.

test suite

The Perl 6 test suite is #roast

TheDamian

#IRC screen name for #Damian Conway, writer of the original Exegeses.

TimToady

#IRC screen name for #Larry Wall, creator of Perl. The name comes from the pronunciation of #TIMTOWTDI as a word.

token

In this context, a token is a regex that does not backtrack. In general, tokens are extracted from the source program while #Lexing.

Thunk

A piece of code that isn't immediately executed, but doesn't have an independent scope.

Tight and loose precedence

In this context, tight or tighter refers to precedence rules and is the opposite of looser. Precedence rules for new terms are always expressed in relationship with other terms, so is tighter implies that operands with that operator will be grouped before operands with the looser operator. Operators with tight precedence are grouped with priority to others and are generally tighter than most others; loose exactly the opposite, so it is always convenient to be aware of the exact precedence of all operators used in an expression.

twine

A data structure used to hold a POD string with embedded formatting codes. For example:

=begin pod 
 C<foo> 
 =end pod 
 say $=pod[0].contents[0].contents.perl; 

The output will be:

["", Pod::FormattingCode.new(type => "C", meta => [], config => {}, contents => ["foo"]),""] 

Note the twine is an array with an odd number of elements beginning with a simple string, alternating with formatting code objects and simple strings, and ending with a simple string. (The formatting code objects are intertwined with the strings.) The strings may be empty (as shown in the example). A twine with no formatting code will contain one simple string.

Type objects

A type object is an object that is used to represent a type or a class. Since in object oriented programming everything is an object, classes are objects too, which inherit from the ur-class which, in our case, is Mu.

value

A value is what is actually contained in a container such as a variable. Used in expressions such as lvalue, to indicate that that particular container can be assigned to.

Value type

A type is known as a value type if it is immutable and any instance of that type is interchangeable with any other instance "of the same value"—that is, any instance constructed in the same way. An instance of a value type is often called a value (but should not be confused with #lvalues or #rvalues).

For example, numbers are value types, so a number constructed one place in your program with, for instance, the literal 3 can't be changed in any way—it simply is 3—and any later use of the literal 3 can safely be pointed at the same place in memory as the first with no ill consequences.

Classes doing the roles Numeric and Stringy are among a few examples of built-in value types.

A value type is created by ensuring that an instance of the value type is immutable (i.e., its attributes cannot be modified after construction) and that its WHICH method returns the same thing every time an instance with the same value is constructed (and conversely returns a different thing every time an instance with a different value is constructed).

The language is free to optimize based on the assumption that equivalent instances of value types are interchangeable, but you should not depend on any such optimization. For instance, if you want clone to return an instance of self, or you want instance construction to be memoized so that re-construction of a previously-constructed value always returns the same instance, you currently must override this behavior yourself.

(The same would hold true of object finalization, but if your instances need special destruction behavior, you almost certainly do not actually have a value type. Values should be thought of as "timeless" and existing in some ideal form outside of your program's memory, like natural values are.)

Variable

A variable is a name for a container.

Variable Interpolation

The value of variables is interpolated into strings by simply inserting that variable into the string:

my $polation="polation";
say "inter$polation";# OUTPUT: «interpolation␤»

This might need curly braces in case it precedes some alphanumeric characters

my $inter="inter";
say "{$inter}polation"; # OUTPUT: «interpolation␤»

Interpolation occurs in string context, so a valid stringification method must exist for the class. More general interpolation can be achieved using the double q quoting constructs.

Virtual Machine

A virtual machine is the Perl compiler entity that executes the bytecode. It can optimize the bytecode or generate machine code Just in Time. Examples are #MoarVM, #Parrot (who are intended to run Perl 6) and more generic virtual machines such as JVM and Javascript.

whitespace

A character or group of blank characters, used to separate words. An example is the space character « ».

6model

6model is used in the MoarVM, and provides primitives used to create an object system. It is described in this presentation by Jonathan Worthington and implemented here in MoarVM.

21 Grammar Tutorial

An introduction to grammars

Before We Start

Why grammars?

Grammars parse strings and return data structures from those strings. Grammars can be used to prepare a program for execution, to determine if a program can run at all (if it's a valid program), to break down a web page into constituent parts, or to identify the different parts of a sentence, among other things.

When would I use grammars?

If you have strings to tame or interpret, grammars provide the tools to do the job.

The string could be a file that you're looking to break into sections; perhaps a protocol, like SMTP, where you need to specify which "commands" come after what user-supplied data; maybe you're designing your own domain specific language. Grammars can help.

The broad concept of grammars

Regular expressions (Regexes) work well for finding patterns in strings. However, for some tasks, like finding multiple patterns at once, or combining patterns, or testing for patterns that may surround strings regular expressions, alone, are not enough.

When working with HTML, you could define a grammar to recognize HTML tags, both the opening and closing elements, and the text in between. You could then organize these elements into data structures, such as arrays or hashes.

Getting More Technical

The conceptual overview

Grammars are a special kind of class. You declare and define a grammar exactly as you would any other class, except that you use the grammar keyword instead of class.

grammar G { ... } 

Grammars are made up of methods that define a regex, a token, or a rule. These are all varieties of different types of match methods. Once you have a grammar defined, you call it and pass in a string for parsing.

my $matchObject = G.parse($string); 

Now, you may be wondering, if I have all these regexes defined that just return their results, how does that help with parsing strings that may be ahead or backwards in a string, or things that need to be combined from many of those regexes... And that's where grammar actions come in.

For every "method" you match in your grammar, you get an action you can use to act on that match. You also get an overarching action that you can use to tie together all your matches and to build a data structure. This overarching method is called TOP by default.

The technical overview

As already mentioned, grammars are declared using the grammar keyword and its "methods" are declared with regex, or token, or rule.

When a method (regex, token or rule) matches in the grammar, the string matched is put into a match object and keyed with the same name as the method.

grammar G { 
     token TOP { <thingy> .* } 
     token thingy { 'clever_text_keyword' } 
 } 

If you were to use my $match = G.parse($string) and your string started with 'clever_text_keyword', you would get a match object back that contained 'clever_text_keyword' keyed by the name of <thingy> in your match object.

The TOP method (whether regex, token, or rule) is the overarching pattern that must match everything (by default). If the parsed string doesn't match the TOP regex, your returned match object will be empty (Nil).

As you can see above, in TOP, the <thingy> token is mentioned. The <thingy> is defined on the next line. That means that 'clever_text_keyword' must be the first thing in the string, or the grammar parse will fail and we'll get an empty match. This is great for recognizing a malformed string that should be discarded.

Learning By Example - a REST Contrivance

Let's suppose we'd like to parse a URI into the component parts that make up a RESTful request. We want the URIs to work like this:

So, if we have "/product/update/7/notify", we would want our grammar to give us a match object that has a subject of "product", a command of "update", and data of "7/notify".

We'll start by defining a grammar class and some match methods for the subject, command, and data. We'll use the token declarator since we don't care about whitespace.

grammar REST { 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 

So far, this REST grammar says we want a subject that will be just word characters, a command that will be just word characters, and data that will be everything else left in the string.

Next, we'll want to arrange these matching tokens within the larger context of the URI. That's what the TOP method allows us to do. We'll add the TOP method and place the names of our tokens within it, together with the rest of the patterns that makes up the overall pattern. Note how we're building a larger regex from our named regexes.

grammar REST { 
     token TOP     { '/' <subject> '/' <command> '/' <data> } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 

With this code, we can already get the three parts of our RESTful request:

my $match = REST.parse('/product/update/7/notify'); 
 say $match; 
 
 # OUTPUT: «「/product/update/7/notify」␤ 
 #          subject => 「product」 
 #          command => 「update」 
 #          data => 「7/notify」» 

The data can be accessed directly by using $match<subject> or $match<command> or $match<data> to return the values parsed. They each contain match objects that you can work further with, such as coercing into a string ( $match<command>.Str ).

Adding some flexibility

So far, the grammar will handle retrieves, deletes and updates. However, a create command doesn't have the third part (the data portion). This means the grammar will fail to match if we try to parse a create URI. To avoid this, we need to make that last data position match optional, along with the '/' preceding it. This is accomplished by adding a question mark to the grouped '/' and data components of the TOP token, to indicate their optional nature, just like a normal regex.

So, now we have:

grammar REST { 
     token TOP     { '/' <subject> '/' <command> [ '/' <data> ]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 
 
 my $m = REST.parse('/product/create'); 
 say $m<subject>, $m<command>; 
 
 # OUTPUT: «「product」「create」␤» 

Next, assume that the URIs will be entered manually by a user and that the user might accidentally put spaces between the '/'s. If we wanted to accommodate for this, we could replace the '/'s in TOP with a token that allowed for spaces.

grammar REST { 
     token TOP     { <slash><subject><slash><command>[<slash><data>]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 
     token slash   { \s* '/' \s* } 
 } 
 
 my $m = REST.parse('/ product / update /7 /notify'); 
 say $m; 
 
 # OUTPUT: «「/ product / update /7 /notify」␤ 
 #          slash => 「/ 」 
 #          subject => 「product」 
 #          slash => 「 / 」 
 #          command => 「update」 
 #          slash => 「 /」 
 #          data => 「7 /notify」» 

We're getting some extra junk in the match object now, with those slashes. There's techniques to clean that up that we'll get to later.

Inheriting from a grammar

Since grammars are classes, they behave, OOP-wise, in the same way as any other class; specifically, they can inherit from base classes that include some tokens or rules, this way:

grammar Letters { 
     token letters { \w+ } 
 } 
 
 grammar Quote-Quotes { 
     token quote { "\""|"`"|"'" } 
 } 
 
 grammar Quote-Other { 
     token quote { "|"|"/"|"¡" } 
 } 
 
 grammar Quoted-Quotes is Letters is Quote-Quotes { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 grammar Quoted-Other is Letters is Quote-Other { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 my $quoted = q{"enhanced"}; 
 my $parsed = Quoted-Quotes.parse($quoted); 
 say $parsed; 
 #OUTPUT: 
 #「"enhanced"」 
 # quote => 「"」 
 # letters => 「enhanced」 
 #quote => 「"」 
 
 $quoted = "|barred|"; 
 $parsed = Quoted-Other.parse($quoted); 
 say $parsed; 
 #OUTPUT: 
 #|barred|」 
 #quote => 「|」 
 #letters => 「barred」 
 #quote => 「|」 

This example uses multiple inheritance to compose two different grammars by varying the rules that correspond to quotes. In this case, besides, we are rather using composition than inheritance, so we could use Roles instead of inheritance.

role Letters { 
     token letters { \w+ } 
 } 
 
 role Quote-Quotes { 
     token quote { "\""|"`"|"'" } 
 } 
 
 role Quote-Other { 
     token quote { "|"|"/"|"¡" } 
 } 
 
 grammar Quoted-Quotes does Letters does Quote-Quotes { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 grammar Quoted-Other does Letters does Quote-Other { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 
 } 

Will output exactly the same as the code above. Symptomatic of the difference between Classes and Roles, a conflict like defining token quote twice using Role composition will result in an error:

grammar Quoted-Quotes does Letters does Quote-Quotes does Quote-Other { ... } 
 # OUTPUT: ... Error while compiling ... Method 'quote' must be resolved ... 

Adding some constraints

We want our RESTful grammar to allow for CRUD operations only. Anything else we want to fail to parse. That means our "command" above should have one of four values: create, retrieve, update or delete.

There are several ways to accomplish this. For example, you could change the command method:

token command { \w+ } 
 
 # …becomes… 
 
 token command { 'create'|'retrieve'|'update'|'delete' } 

For a URI to parse successfully, the second part of the string between '/'s must be one of those CRUD values, otherwise the parsing fails. Exactly what we want.

There's another technique that provides greater flexibility and improved readability when options grow large: proto-regexes.

To utilize these proto-regexes (multimethods, in fact) to limit ourselves to the valid CRUD options, we'll replace token command with the following:

proto token command {*} 
 token command:sym<create>   { <sym> } 
 token command:sym<retrieve> { <sym> } 
 token command:sym<update>   { <sym> } 
 token command:sym<delete>   { <sym> } 

The sym keyword is used to create the various proto-regex options. Each option is named (e.g., sym<update>), and for that option's use, a special <sym> token is auto-generated with the same name.

The <sym> token, as well as other user-defined tokens, may be used in the proto-regex option block to define the specific match condition. Regex tokens are compiled forms and, once defined, cannot subsequently be modified by adverb actions (e.g., :i). Therefore, as it's auto-generated, the special <sym> token is useful only where an exact match of the option name is required.

If, for one of the proto-regex options, a match condition occurs, then the whole proto's search terminates. The matching data, in the form of a match object, is assigned to the parent proto token. If the special <sym> token was employed and formed all or part of the actual match, then it's preserved as a sub-level in the match object, otherwise it's absent.

Using proto-regex like this gives us a lot of flexibility. For example, instead of returning <sym>, which in this case is the entire string that was matched, we could instead enter our own string, or do other funny stuff. We could do the same with the token subject method and limit it also to only parsing correctly on valid subjects (like 'part' or 'people', etc.).

Putting our RESTful grammar together

This is what we have for processing our RESTful URIs, so far:

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 

Let's look at various URIs and see how they work with our grammar.

my @uris = ['/product/update/7/notify', 
             '/product/create', 
             '/item/delete/4']; 
 
 for @uris -> $uri { 
     my $m = REST.parse($uri); 
     say "Sub: $m<subject> Cmd: $m<command> Dat: $m<data>"; 
 } 
 
 # OUTPUT: «Sub: product Cmd: update Dat: 7/notify␤ 
 #          Sub: product Cmd: create Dat: ␤ 
 #          Sub: item Cmd: delete Dat: 4␤» 

Note that since <data> matches nothing on the second string, $m<data> will be Nil, then using it in string context in the say function warns.

With just this part of a grammar, we're getting almost everything we're looking for. The URIs get parsed and we get a data structure with the data.

The data token returns the entire end of the URI as one string. The 4 is fine. However from the '7/notify', we only want the 7. To get just the 7, we'll use another feature of grammar classes: actions.

Grammar Actions

Grammar actions are used within grammar classes to do things with matches. Actions are defined in their own classes, distinct from grammar classes.

You can think of grammar actions as a kind of plug-in expansion module for grammars. A lot of the time you'll be happy using grammars all by their own. But when you need to further process some of those strings, you can plug in the Actions expansion module.

To work with actions, you use a named parameter called actions which should contain an instance of your actions class. With the code above, if our actions class called REST-actions, we would parse the URI string like this:

my $matchObject = REST.parse($uri, actions => REST-actions.new); 
 
 #   …or if you prefer… 
 
 my $matchObject = REST.parse($uri, :actions(REST-actions.new)); 

If you name your action methods with the same name as your grammar methods (tokens, regexes, rules), then when your grammar methods match, your action method with the same name will get called automatically. The method will also be passed the corresponding match object (represented by the $/ variable).

Let's turn to an example.

Grammars by example with actions

Here we are back to our grammar.

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 

Recall that we want to further process the data token "7/notify", to get the 7. To do this, we'll create an action class that has a method with the same name as the named token. In this case, our token is named data so our method is also named data.

class REST-actions 
 { 
     method data($/) { $/.split('/') } 
 } 

Now when we pass the URI string through the grammar, the data token match will be passed to the REST-actions' data method. The action method will split the string by the '/' character and the first element of the returned list will be the ID number (7 in the case of "7/notify").

But not really; there's a little more.

Keeping grammars with actions tidy with make and made

If the grammar calls the action above on data, the data method will be called, but nothing will show up in the big TOP grammar match result returned to our program. In order to make the action results show up, we need to call make on that result. The result can be many things, including strings, array or hash structures.

You can imagine that the make places the result in a special contained area for a grammar. Everything that we make can be accessed later by made.

So instead of the REST-actions class above, we should write:

class REST-actions 
 { 
     method data($/) { make $/.split('/') } 
 } 

When we add make to the match split (which returns a list), the action will return a data structure to the grammar that will be stored separately from the data token of the original grammar. This way, we can work with both if we need to.

If we want to access just the ID of 7 from that long URI, we access the first element of the list returned from the data action that we made:

my $uri = '/product/update/7/notify'; 
 
 my $match = REST.parse($uri, actions => REST-actions.new); 
 
 say $match<data>.made[0];  # OUTPUT: «7␤» 
 say $match<command>.Str;   # OUTPUT: «update␤» 

Here we call made on data, because we want the result of the action that we made (with make) to get the split array. That's lovely! But, wouldn't it be lovelier if we could make a friendlier data structure that contained all of the stuff we want, rather than having to coerce types and remember arrays?

Just like Grammar's TOP, which matches the entire string, actions have a TOP method as well. We can make all of the individual match components, like data or subject or command, and then we can place them in a data structure that we will make in TOP. When we return the final match object, we can then access this data structure.

To do this, we add the method TOP to the action class and make whatever data structure we like from the component pieces.

So, our action class becomes:

class REST-actions 
 { 
     method TOP ($/) { 
         make { subject => $<subject>.Str, 
                command => $<command>.Str, 
                data    => $<data>.made } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Here in the TOP method, the subject remains the same as the subject we matched in the grammar. Also, command returns the valid <sym> that was matched (create, update, retrieve, or delete). We coerce each into .Str, as well, since we don't need the full match object.

We want to make sure to use the made method on the $<data> object, since we want to access the split one that we made with make in our action, rather than the proper $<data> object.

After we make something in the TOP method of a grammar action, we can then access all the custom values by calling the made method on the grammar result object. The code now becomes

my $uri = '/product/update/7/notify'; 
 
 my $match = REST.parse($uri, actions => REST-actions.new); 
 
 my $rest = $match.made; 
 say $rest<data>[0];   # OUTPUT: «7␤» 
 say $rest<command>;   # OUTPUT: «update␤» 
 say $rest<subject>;   # OUTPUT: «product␤» 

If the complete return match object is not needed, you could return only the made data from your action's TOP.

my $uri = '/product/update/7/notify'; 
 
 my $rest = REST.parse($uri, actions => REST-actions.new).made; 
 
 say $rest<data>[0];   # OUTPUT: «7␤» 
 say $rest<command>;   # OUTPUT: «update␤» 
 say $rest<subject>;   # OUTPUT: «product␤» 

Oh, did we forget to get rid of that ugly array element number? Hmm. Let's make something new in the grammar's custom return in TOP... how about we call it subject-id and have it set to element 0 of <data>.

class REST-actions 
 { 
     method TOP ($/) { 
         make { subject    => $<subject>.Str, 
                command    => $<command>.Str, 
                data       => $<data>.made, 
                subject-id => $<data>.made[0] } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Now we can do this instead:

my $uri = '/product/update/7/notify'; 
 
 my $rest = REST.parse($uri, actions => REST-actions.new).made; 
 
 say $rest<command>;    # OUTPUT: «update␤» 
 say $rest<subject>;    # OUTPUT: «product␤» 
 say $rest<subject-id>; # OUTPUT: «7␤» 

Here's the final code:

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 
 
 
 class REST-actions 
 { 
     method TOP ($/) { 
         make { subject    => $<subject>.Str, 
                command    => $<command>.Str, 
                data       => $<data>.made, 
                subject-id => $<data>.made[0] } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Add actions directly

Above we see how to associate grammars with action objects and perform actions on the match object. However, when we want to deal with the match object, that isn't the only way. See the example below:

grammar G { 
   rule TOP { <function-define> } 
   rule function-define { 
     'sub' <identifier> 
     { 
       say "func " ~ $<identifier>.made; 
       make $<identifier>.made; 
     } 
     '(' <parameter> ')' '{' '}' 
     { say "end " ~ $/.made; } 
   } 
   token identifier { \w+ { make ~$/; } } 
   token parameter { \w+ { say "param " ~ $/; } } 
 } 
 
 G.parse('sub f ( a ) { }'); 
 # OUTPUT: «func f␤param a␤end f␤» 

This example is a reduced portion of a parser. Let's focus more on the feature it shows.

First, we can add actions inside the grammar itself, and such actions are performed once the control flow of the regex arrives at them. Note that action object's method will always be performed after the whole regex item matched. Second, it shows what make really does, which is no more than a sugar of $/.made = .... And this trick introduces a way to pass messages from within a regex item.

Hopefully this has helped introduce you to the grammars in Perl 6 and shown you how grammars and grammar action classes work together. For more information, check out the more advanced Perl Grammar Guide.

For more grammar debugging, see Grammar::Debugger. This provides breakpoints and color-coded MATCH and FAIL output for each of your grammar tokens.

22 Grammars

Parsing and interpreting text

Grammar is a powerful tool used to destructure text and often to return data structures that have been created by interpreting that text.

For example, Perl 6 is parsed and executed using a Perl 6-style grammar.

An example that's more practical to the common Perl 6 user is the JSON::Tiny module, which can deserialize any valid JSON file, however the deserializing code is written in less than 100 lines of simple, extensible code.

If you didn't like grammar in school, don't let that scare you off grammars. Grammars allow you to group regexes, just as classes allow you to group methods of regular code.

Named Regexes

The main ingredient of grammars is named regexes. While the syntax of Perl 6 Regexes is outside the scope of this document, named regexes have a special syntax, similar to subroutine definitions:

In fact, named regexes can even take extra arguments, using the same syntax as subroutine parameter lists

my regex number { \d+ [ \. \d+ ]? } 

In this case, we have to specify that the regex is lexically scoped using the my keyword, because named regexes are normally used within grammars.

Being named gives us the advantage of being able to easily reuse the regex elsewhere:

say so "32.51" ~~ &number;                         # OUTPUT: «True␤» 
 say so "15 + 4.5" ~~ /<number>\s* '+' \s*<number>/ # OUTPUT: «True␤» 

regex isn't the only declarator for named regexes. In fact, it's the least common. Most of the time, the token or rule declarators are used. These are both ratcheting, which means that the match engine won't back up and try again if it fails to match something. This will usually do what you want, but isn't appropriate for all cases:

my regex works-but-slow { .+ q } 
 my token fails-but-fast { .+ q } 
 my $s = 'Tokens won\'t backtrack, which makes them fail quicker!'; 
 say so $s ~~ &works-but-slow; # OUTPUT: «True␤» 
 say so $s ~~ &fails-but-fast; # OUTPUT: «False␤» 
                               # the entire string get taken by the .+ 

Note that non-backtracking works on terms, that is, as the example below, if you have matched something, then you will never backtrack. But when you fail to match, if there is another candidate introduced by | or ||, you will retry to match again.

my token tok-a { .* d  }; 
 my token tok-b { .* d | bd }; 
 say so "bd" ~~ &tok-a;        # OUTPUT: «False␤» 
 say so "bd" ~~ &tok-b;        # OUTPUT: «True␤» 

Rules

The only difference between the token and rule declarators is that the rule declarator causes :sigspace to go into effect for the Regex:

my token non-space-y { 'once' 'upon' 'a' 'time' } 
 my rule space-y { 'once' 'upon' 'a' 'time' } 
 say so 'onceuponatime'    ~~ &non-space-y; # OUTPUT: «True␤» 
 say so 'once upon a time' ~~ &non-space-y; # OUTPUT: «False␤» 
 say so 'onceuponatime'    ~~ &space-y;     # OUTPUT: «False␤» 
 say so 'once upon a time' ~~ &space-y;     # OUTPUT: «True␤» 

Creating Grammars

Group of named regexes that form a formal grammar

Grammar is the superclass that classes automatically get when they are declared with the grammar keyword instead of class. Grammars should only be used to parse text; if you wish to extract complex data, you can add actions within the grammar, or an action object is recommended to be used in conjunction with the grammar.

Proto regexes

Grammars are composed of rules, tokens and regexes; they are actually methods, since grammars are classes. These methods can share a name and functionality in common, and thus can use proto.

For instance, if you have a lot of alternations, it may become difficult to produce readable code or subclass your grammar. In the Actions class below, the ternary in method TOP is less than ideal and it becomes even worse the more operations we add:

grammar Calculator {
    token TOP { [ <add> | <sub> ] }
    rule  add { <num> '+' <num> }
    rule  sub { <num> '-' <num> }
    token num { \d+ }
}

class Calculations {
    method TOP ($/) { make $<add> ?? $<add>.made !! $<sub>.made; }
    method add ($/) { make [+] $<num>; }
    method sub ($/) { make [-] $<num>; }
}

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

To make things better, we can use proto regexes that look like :sym<...> adverbs on tokens:

grammar Calculator {
    token TOP { <calc-op> }

    proto rule calc-op          {*}
          rule calc-op:sym<add> { <num> '+' <num> }
          rule calc-op:sym<sub> { <num> '-' <num> }

    token num { \d+ }
}

class Calculations {
    method TOP              ($/) { make $<calc-op>.made; }
    method calc-op:sym<add> ($/) { make [+] $<num>; }
    method calc-op:sym<sub> ($/) { make [-] $<num>; }
}

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

In the grammar, the alternation has now been replaced with <calc-op>, which is essentially the name of a group of values we'll create. We do so by defining a rule prototype with proto rule calc-op. Each of our previous alternations have been replaced by a new rule calc-op definition and the name of the alternation is attached with :sym<> adverb.

In the actions class, we now got rid of the ternary operator and simply take the .made value from the $<calc-op> match object. And the actions for individual alternations now follow the same naming pattern as in the grammar: method calc-op:sym<add> and method calc-op:sym<sub>.

The real beauty of this method can be seen when you subclass that grammar and actions class. Let's say we want to add a multiplication feature to the calculator:

grammar BetterCalculator is Calculator { 
     rule calc-op:sym<mult> { <num> '*' <num> } 
 } 
 
 class BetterCalculations is Calculations { 
     method calc-op:sym<mult> ($/) { make [*] $<num> } 
 } 
 
 say BetterCalculator.parse('2 * 3', actions => BetterCalculations).made; 
 
 # OUTPUT: «6␤» 

All we had to add are additional rule and action to the calc-op group and the thing works—all thanks to proto regexes.

Special Tokens

TOP

grammar Foo {
    token TOP { \d+ }
}

The TOP token is the default first token attempted to match when parsing with a grammar. Note that if you're parsing with .parse method, token TOP is automatically anchored to the start and end of the string. If you don't want to parse the whole string, look up .subparse.

Using rule TOP or regex TOP are also acceptable.

A different token can be chosen to be matched first using the :rule named argument to .parse, .subparse, or .parsefile. These are all Grammar methods.

ws

When rule instead of token is used, any whitespace after an atom is turned into a non-capturing call to ws, written as <.ws> where . means non-capturing. That is to say:

rule entry { <key> '=' <value> }

Is the same as:

token entry { <key> <.ws> '=' <.ws> <value> <.ws> }

The default ws matches one or more whitespace characters (\s) or a word boundary (<|w>):

# First <.ws> matches word boundary at the start of the line
# and second <.ws> matches the whitespace between 'b' and 'c'
say 'ab   c' ~~ /<.ws> ab <.ws> c /; # OUTPUT: «「ab   c」␤»

# Failed match: there is neither any whitespace nor a word
# boundary between 'a' and 'b'
say 'ab' ~~ /. <.ws> b/;             # OUTPUT: «Nil␤»

# Successful match: there is a word boundary between ')' and 'b'
say ')b' ~~ /. <.ws> b/;             # OUTPUT: «「)b」␤»

You can also redefine the default ws token:

grammar Foo {
    rule TOP { \d \d }
}.parse: "4   \n\n 5"; # Succeeds

grammar Bar {
    rule TOP { \d \d }
    token ws { \h*   }
}.parse: "4   \n\n 5"; # Fails

sym

The <sym> token can be used inside proto regexes to match the string value of the :sym adverb for that particular regex:

grammar Foo {
    token TOP { <letter>+ }
    proto token letter {*}
    token letter:sym<P> { <sym> }
    token letter:sym<e> { <sym> }
    token letter:sym<r> { <sym> }
    token letter:sym<l> { <sym> }
    token letter:sym<*> {   .   }
}.parse("I ♥ Perl", actions => class {
    method TOP($/) { make $<letter>.grep(*.<sym>).join }
}).made.say; # OUTPUT: «Perl␤»

This comes in handy when you're already differentiating the proto regexes with the strings you're going to match, as using <sym> token prevents repetition of those strings.

Always Succeed Assertion

The <?> is the always succeed assertion. When used as a grammar token, it can be used to trigger an Action class method. In the following grammar we look for Arabic digits and define a succ token with the always succeed assertion.

In the action class, we use calls to the succ method to do set up (in this case, we prepare a new element in @!numbers). In the digit method, we convert an Arabic digit into a Devanagari digit and add it to the last element of @!numbers. Thanks to succ, the last element will always be the number for the currently parsed digit digits.

grammar Digifier {
    rule TOP {
        [ <.succ> <digit>+ ]+
    }
    token succ   { <?> }
    token digit { <[0..9]> }
}

class Devanagari {
    has @!numbers;
    method digit ($/) { @!numbers[*-1] ~= $/.ord.&[+](2358).chr }
    method succ  ($)  { @!numbers.push: ''     }
    method TOP   ($/) { make @!numbers[^(*-1)] }
}

say Digifier.parse('255 435 777', actions => Devanagari.new).made;
# OUTPUT: «(२५५ ४३५ ७७७)␤»

Methods in Grammar

It's fine to use methods instead of rules or tokens in a grammar, as long as they return a Cursor:

grammar DigitMatcher {
    method TOP (:$full-unicode) {
        $full-unicode ?? self.num-full !! self.num-basic;
    }
    token num-full  { \d+ }
    token num-basic { <[0..9]>+ }
}

The grammar above will attempt different matches depending on the arguments provided by parse methods:

say +DigitMatcher.subparse: '12७१७९०९', args => \(:full-unicode); 
 # OUTPUT: «12717909␤» 
 
 say +DigitMatcher.subparse: '12७१७९०९', args => \(:!full-unicode); 
 # OUTPUT: «12␤» 

Dynamic Variables in Grammars

Variables can be defined in tokens by prefixing the lines of code defining them with :. Arbitrary code can be embedded anywhere in a token by surrounding it with curly braces. This is useful for keeping state between tokens, which can be used to alter how the grammar will parse text. Using dynamic variables (variables with $*, @*, &*, %* twigils) in tokens cascades down through all tokens defined thereafter within the one where it's defined, avoiding having to pass them from token to token as arguments.

One use for dynamic variables is guards for matches. This example uses guards to explain which regex classes parse whitespace literally:

grammar GrammarAdvice {
    rule TOP {
        :my Int $*USE-WS;
        "use" <type> "for" <significance> "whitespace by default"
    }
    token type {
        | "rules"   { $*USE-WS = 1 }
        | "tokens"  { $*USE-WS = 0 }
        | "regexes" { $*USE-WS = 0 }
    }
    token significance {
        | <?{ $*USE-WS == 1 }> "significant"
        | <?{ $*USE-WS == 0 }> "insignificant"
    }
}

Here, text such as "use rules for significant whitespace by default" will only match if the state assigned by whether rules, tokens, or regexes are mentioned matches with the correct guard:

say GrammarAdvice.subparse("use rules for significant whitespace by default"); 
 # OUTPUT: «use rules for significant whitespace by default» 
 
 say GrammarAdvice.subparse("use tokens for insignificant whitespace by default"); 
 # OUTPUT: «use tokens for insignificant whitespace by default» 
 
 say GrammarAdvice.subparse("use regexes for insignificant whitespace by default"); 
 # OUTPUT: «use regexes for insignificant whitespace by default» 
 
 say GrammarAdvice.subparse("use regexes for significant whitespace by default") 
 # OUTPUT: #<failed match> 

Action Objects

A successful grammar match gives you a parse tree of Match objects, and the deeper that match tree gets, and the more branches in the grammar are, the harder it becomes to navigate the match tree to get the information you are actually interested in.

To avoid the need for diving deep into a match tree, you can supply an actions object. After each successful parse of a named rule in your grammar, it tries to call a method of the same name as the grammar rule, giving it the newly created Match object as a positional argument. If no such method exists, it is skipped.

Here is a contrived example of a grammar and actions in action:

grammar TestGrammar { 
     token TOP { \d+ } 
 } 
 
 class TestActions { 
     method TOP($/) { 
         $/.make(2 + $/); 
     } 
 } 
 
 my $match = TestGrammar.parse('40', actions => TestActions.new); 
 say $match;         # OUTPUT: «「40」␤» 
 say $match.made;    # OUTPUT: «42␤» 

An instance of TestActions is passed as named argument actions to the parse call, and when token TOP has matched successfully, it automatically calls method TOP, passing the match object as an argument.

To make it clear that the argument is a match object, the example uses $/ as a parameter name to the action method, though that's just a handy convention, nothing intrinsic. $match would have worked too. (Though using $/ does give the advantage of providing $<capture> as a shortcut for $/<capture>).

A slightly more involved example follows:

grammar KeyValuePairs { 
     token TOP { 
         [<pair> \n+]* 
     } 
 
     token ws { 
         \h* 
     } 
 
     rule pair { 
         <key=.identifier> '=' <value=.identifier> 
     } 
     token identifier { 
         \w+ 
     } 
 } 
 
 class KeyValuePairsActions { 
     method pair      ($/) { 
         $/.make: $<key>.made => $<value>.made 
     } 
     method identifier($/) { 
         # subroutine `make` is the same as calling .make on $/ 
         make ~$/ 
     } 
     method TOP ($match) { 
         # can use any variable name for parameter, not just $/ 
         $match.make: $match<pair>».made 
     } 
 } 
 
 my $actions = KeyValuePairsActions; 
 my $res = KeyValuePairs.parse(q:to/EOI/, :$actions).made; 
     second=b 
     hits=42 
     perl=6 
     EOI 
 
 for @$res -> $p { 
     say "Key: $p.key()\tValue: $p.value()"; 
 } 

This produces the following output:

Key: second     Value: b 
 Key: hits       Value: 42 
 Key: perl       Value: 6 

Rule pair, which parsed a pair separated by an equals sign, aliases the two calls to token identifier to separate capture names to make them available more easily and intuitively. The corresponding action method constructs a Pair object, and uses the .made property of the sub match objects. So it (like the action method TOP too) exploits the fact that action methods for submatches are called before those of the calling/outer regex. So action methods are called in post-order.

The action method TOP simply collects all the objects that were .made by the multiple matches of the pair rule, and returns them in a list.

Also note that KeyValuePairsActions was passed as a type object to method parse, which was possible because none of the action methods use attributes (which would only be available in an instance).

In other cases, action methods might want to keep state in attributes. Then of course you must pass an instance to method parse.

Note that token ws is special: when :sigspace is enabled (and it is when we are using rule), it replaces certain whitespace sequences. This is why the spaces around the equals sign in rule pair work just fine and why the whitespace before closing } does not gobble up the newlines looked for in token TOP.

23 Hashes and maps

Working with associative arrays/dictionaries/hashes

The Associative role and associative classes

The Associative role underlies hashes and maps, as well as other classes such as MixHash. It defines the two types that will be used in associative classes; by default, you can use anything (literally, since any class that subclasses Any can be used) as a key and keyof methods.

By default, any object declared with the % sigil will get the Associative role, and will by default behave like a hash, but this role will only provide the two methods above, as well as the default Hash behavior.

say (%).^name ;# OUTPUT: «Hash␤»

Inversely, you cannot use the % sigil if the Associative role is not mixed in, but since this role does not have any associated properties, you will have to redefine the behavior of the hash subscript operator. In order to do that, there are several functions you will have to override:

class Logger does Associative[Cool,DateTime] { 
     has %.store; 
 
     method log( Cool $event ) { 
         %.store{ DateTime.new( now ) } = $event; 
     } 
 
     multi method AT-KEY ( ::?CLASS:D: $key) { 
         my @keys = %.store.keys.grep( /$key/ ); 
         %.store{ @keys }; 
     } 
 
     multi method EXISTS-KEY (::?CLASS:D: $key) { 
         %.store.keys.grep( /$key/ )??True!!False; 
     } 
 
     multi method DELETE-KEY (::?CLASS:D: $key) { 
         X::Assignment::RO.new.throw; 
     } 
 
     multi method ASSIGN-KEY (::?CLASS:D: $key, $new) { 
         X::Assignment::RO.new.throw; 
     } 
 
     multi method BIND-KEY (::?CLASS:D: $key, \new){ 
         X::Assignment::RO.new.throw; 
     } 
 } 
 say Logger.of;                   # OUTPUT: «(Cool)» 
 my %logger := Logger.new; 
 say %logger.of;                  # OUTPUT: «(Cool)» 
 
 %logger.log( "Stuff" ); 
 %logger.log( "More stuff"); 
 
 say %logger<2018-05-26>;         # OUTPUT: «(More stuff Stuff)» 
 say %logger<2018-04-22>:exists;  # OUTPUT: «False» 
 

In this case, we are defining a logger with Associative semantics that would be able to use dates (or a part of them) as keys. Since we are parametrizing Associative to those particular classes, of will return the value type we have used, Cool in this case (we can log lists or strings only). Mixing the Associative role gives it the right to use the % sigil; binding is needed in the definition since %-sigilled variables get by default the Hash type.

This log is going to be append-only, that is why we escape the associative array metaphor to use a log method to add new events to the log. Once they have been added, however, we can retrieve them by date or check if they exist. For the first we have to override the AT-KEY multi method, for the latter EXIST-KEY. In the last two statements, we show how the subscript operation invokes AT-KEY, while the :exists adverb invokes EXISTS-KEY.

We override DELETE-KEY, ASSIGN-KEY and BIND-KEY, but only to throw an exception. Attempting to assign, delete or bind a value to a key will result in a Cannot modify an immutable Str (value) exception thrown.

Making classes associative provides a very convenient way of using and working with them using hashes; an example can be seen in Cro, which uses it extensively for the convenience of using hashes to define structured requests and express its response.

Mutable hashes and immutable maps

A Hash is a mutable mapping from keys to values (called dictionary, hash table or map in other programming languages). The values are all scalar containers, which means you can assign to them. Maps are, on the other hand, immutable. Once a key has been paired with a value, this pairing cannot be changed.

Maps and hashes are usually stored in variables with the percent % sigil, which is used to indicate they are Associative.

Hash and map elements are accessed by key via the { } postcircumfix operator:

say %*ENV{'HOME', 'PATH'}.perl;
# OUTPUT: «("/home/camelia", "/usr/bin:/sbin:/bin")␤»

The general Subscript rules apply providing shortcuts for lists of literal strings, with and without interpolation.

my %h = oranges => 'round', bananas => 'bendy';
say %h<oranges bananas>;
# OUTPUT: «(round bendy)␤»

my $fruit = 'bananas';
say %h«oranges "$fruit"»;
# OUTPUT: «(round bendy)␤»

You can add new pairs simply by assigning to an unused key:

my %h;
%h{'new key'} = 'new value';

Hash assignment

Assigning a list of elements to a hash variable first empties the variable, and then iterates the elements of the right-hand side. If an element is a Pair, its key is taken as a new hash key, and its value as the new hash value for that key. Otherwise the value is coerced to Str and used as a hash key, while the next element of the list is taken as the corresponding value.

my %h = 'a', 'b', c => 'd', 'e', 'f';

Same as

my %h = a => 'b', c => 'd', e => 'f';

or

my %h = <a b c d e f>;

or even

my %h = %( a => 'b', c => 'd', e => 'f')

or

my $h = { a => 'b', c => 'd', e => 'f'};

Please note that curly braces are used only in the case that we are not assigning it to a %-sigilled variable; in case we use it for a %-sigilled variable we will get an Potential difficulties:␤ Useless use of hash composer on right side of hash assignment; did you mean := instead? error. As this error indicates, however, we can use curly braces as long as we use also binding:

my %h := { a => 'b', c => 'd', e => 'f'};
say %h; # OUTPUT: «{a => b, c => d, e => f}␤»

Nested hashes can also be defined using the same syntax:

my %h =  e => f => 'g';
say %h<e><f>; # OUTPUT: «g␤»

However, what you are defining here is a key pointing to a Pair, which is fine if that is what you want, and if your nested hash has got a single key. But %h<e> will point to a Pair which will have these consequences:

my %h =  e => f => 'g'; 
 %h<e><q> = 'k'; 
 # OUTPUT: «(exit code 1) Pair␤Cannot modify an immutable Str (Nil)␤  in block <unit>» 

This, however, will effectively define a nested hash:

m: my %h =  e => { f => 'g'};
say %h<e>.^name;  # OUTPUT: «Hash␤»
say %h<e><f>;     # OUTPUT: «g␤»

If a Pair is encountered where a value is expected, it is used as a hash value:

my %h = 'a', 'b' => 'c';
say %h<a>.^name;            # OUTPUT: «Pair␤»
say %h<a>.key;              # OUTPUT: «b␤»

If the same key appears more than once, the value associated with its last occurrence is stored in the hash:

my %h = a => 1, a => 2;
say %h<a>;                  # OUTPUT: «2␤»

To assign a hash to a variable which does not have the % sigil, you may use the %() hash constructor:

my $h = %( a => 1, b => 2 );
say $h.^name;               # OUTPUT: «Hash␤»
say $h<a>;                  # OUTPUT: «1␤»

If one or more values reference the topic variable, $_, the right-hand side of the assignment will be interpreted as a Block, not a Hash:

my @people = [ 
     %( id => "1A", firstName => "Andy", lastName => "Adams" ), 
     %( id => "2B", firstName => "Beth", lastName => "Burke" ), 
     # ... 
 ]; 
 
 sub lookup-user (Hash $h) { #`(Do something...) $h } 
 
 my @names = map { 
     # While this creates a hash: 
     my  $query = { name => "$person<firstName> $person<lastName>" }; 
     say $query.^name;      # OUTPUT: «Hash␤» 
 
     # Doing this will create a Block. Oh no! 
     my  $query2 = { name => "$_<firstName> $_<lastName>" }; 
     say $query2.^name;       # OUTPUT: «Block␤» 
     say $query2<name>;       # fails 
 
     CATCH { default { put .^name, ': ', .Str } }; 
     # OUTPUT: «X::AdHoc: Type Block does not support associative indexing.␤» 
     lookup-user($query);   # Type check failed in binding $h; expected Hash but got Block 
 }, @people; 

This would have been avoided if you had used the %() hash constructor. Only use curly braces for creating Blocks.

Hash slices

You can assign to multiple keys at the same time with a slice.

my %h; %h<a b c> = 2 xx *; %h.perl.say;  # OUTPUT: «{:a(2), :b(2), :c(2)}␤»
my %h; %h<a b c> = ^3;     %h.perl.say;  # OUTPUT: «{:a(0), :b(1), :c(2)}␤»

Non-string keys (object hash)

By default keys in { } are forced to strings. To compose a hash with non-string keys, use a colon prefix:

my $when = :{ (now) => "Instant", (DateTime.now) => "DateTime" };

Note that with objects as keys, you often cannot use the <...> construct for key lookup, as it creates only strings and allomorphs. Use the {...} instead:

:{  0  => 42 }<0>.say;   # Int    as key, IntStr in lookup; OUTPUT: «(Any)␤»
:{  0  => 42 }{0}.say;   # Int    as key, Int    in lookup; OUTPUT: «42␤»
:{ '0' => 42 }<0>.say;   # Str    as key, IntStr in lookup; OUTPUT: «(Any)␤»
:{ '0' => 42 }{'0'}.say; # Str    as key, Str    in lookup; OUTPUT: «42␤»
:{ <0> => 42 }<0>.say;   # IntStr as key, IntStr in lookup; OUTPUT: «42␤»

Note: Rakudo implementation currently erroneously applies the same rules for :{ } as it does for { } and can construct a Block in certain circumstances. To avoid that, you can instantiate a parameterized Hash directly. Parameterization of %-sigiled variables is also supported:

my Num %foo1      = "0" => 0e0; # Str keys and Num values
my     %foo2{Int} =  0  => "x"; # Int keys and Any values
my Num %foo3{Int} =  0  => 0e0; # Int keys and Num values
Hash[Num,Int].new: 0, 0e0;      # Int keys and Num values

Now if you want to define a hash to preserve the objects you are using as keys as the exact objects you are providing to the hash to use as keys, then object hashes are what you are looking for.

my %intervals{Instant};
my $first-instant = now;
%intervals{ $first-instant } = "Our first milestone.";
sleep 1;
my $second-instant = now;
%intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
for %intervals.sort -> (:$key, :$value) {
    state $last-instant //= $key;
    say "We noted '$value' at $key, with an interval of {$key - $last-instant}";
    $last-instant = $key;
}

This example uses an object hash that only accepts keys of type Instant to implement a rudimentary, yet type-safe, logging mechanism. We utilize a named state variable for keeping track of the previous Instant so that we can provide an interval.

The whole point of object hashes is to keep keys as objects-in-themselves. Currently object hashes utilize the WHICH method of an object, which returns a unique identifier for every mutable object. This is the keystone upon which the object identity operator (===) rests. Order and containers really matter here as the order of .keys is undefined and one anonymous list is never === to another.

my %intervals{Instant};
my $first-instant = now;
%intervals{ $first-instant } = "Our first milestone.";
sleep 1;
my $second-instant = now;
%intervals{ $second-instant } = "Logging this Instant for spurious raisins.";
say ($first-instant, $second-instant) ~~ %intervals.keys;       # OUTPUT: «False␤»
say ($first-instant, $second-instant) ~~ %intervals.keys.sort;  # OUTPUT: «False␤»
say ($first-instant, $second-instant) === %intervals.keys.sort; # OUTPUT: «False␤»
say $first-instant === %intervals.keys.sort[0];                 # OUTPUT: «True␤»

Since Instant defines its own comparison methods, in our example a sort according to cmp will always provide the earliest instant object as the first element in the List it returns.

If you would like to accept any object whatsoever in your hash, you can use Any!

my %h{Any};
%h{(now)} = "This is an Instant";
%h{(DateTime.now)} = "This is a DateTime, which is not an Instant";
%h{"completely different"} = "Monty Python references are neither DateTimes nor Instants";

There is a more concise syntax which uses binding.

my %h := :{ (now) => "Instant", (DateTime.now) => "DateTime" };

The binding is necessary because an object hash is about very solid, specific objects, which is something that binding is great at keeping track of but about which assignment doesn't concern itself much.

Constraint value types

Place a type object in-between the declarator and the name to constraint the type of all values of a Hash. Use a subset for constraints with a where-clause.

subset Powerful of Int where * > 9000;
my Powerful %h{Str};
put %h<Goku>   = 9001;
try {
    %h<Vegeta> = 900;
    CATCH { when X::TypeCheck::Binding { .message.put } }
}

# OUTPUT:
# 9001
# Type check failed in binding assignval; expected Powerful but got Int (900)

Looping over hash keys and values

A common idiom for processing the elements in a hash is to loop over the keys and values, for instance,

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.kv -> $vowel, $index {
  "$vowel: $index".say;
}

gives output similar to this:

a: 1 
 e: 2 
 o: 4 
 u: 5 
 i: 3 

where we have used the kv method to extract the keys and their respective values from the hash, so that we can pass these values into the loop.

Note that the order of the keys and values printed cannot be relied upon; the elements of a hash are not always stored the same way in memory for different runs of the same program. In fact, since version 2018.05, the order is guaranteed to be different in every invocation. Sometimes one wishes to process the elements sorted on, e.g. the keys of the hash. If one wishes to print the list of vowels in alphabetical order then one would write

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.sort(*.key)>>.kv -> ($vowel, $index) {
  "$vowel: $index".say;
}

which prints

a: 1 
 e: 2 
 i: 3 
 o: 4 
 u: 5 

in alphabetical order as desired. To achieve this result, we sorted the hash of vowels by key (%vowels.sort(*.key)) which we then ask for its keys and values by applying the .kv method to each element via the unary > > hyperoperator resulting in a List of key/value lists. To extract the key/value the variables thus need to be wrapped in parentheses.

An alternative solution is to flatten the resulting list. Then the key/value pairs can be accessed in the same way as with plain .kv:

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.sort(*.key)>>.kv.flat -> $vowel, $index {
  "$vowel: $index".say;
}

You can also loop over a Hash using destructuring.

In place editing of values

There may be times when you would like to modify the values of a hash while iterating over them.

my %answers = illuminatus => 23, hitchhikers => 42;
# OUTPUT: «hitchhikers => 42, illuminatus => 23»
for %answers.values -> $v { $v += 10 }; # Fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot assign to a readonly variable or a value␤»

This is traditionally accomplished by sending both the key and the value as follows.

my %answers = illuminatus => 23, hitchhikers => 42;
for %answers.kv -> $k,$v { %answers{$k} = $v + 10 };

However, it is possible to leverage the signature of the block in order to specify that you would like read-write access to the values.

my %answers = illuminatus => 23, hitchhikers => 42;
for %answers.values -> $v is rw { $v += 10 };

It is not, however, possible to do in-place editing of hash keys, even in the case of object hashes.

24 Haskell to Perl 6 - Nutshell

Learning Perl 6 from Haskell, in a nutshell: What do I already know?

Haskell and Perl 6 are very different languages. This is obvious. However, that does not mean there are not similarities or shared ideas! This page attempts to get a Haskell user up and running with Perl 6. The Haskell user may find that they need not abandon all of their Haskelly thoughts while scripting in Perl 6.

Note that this should not be mistaken for a beginner tutorial or overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Haskell background.

Types

Types vs Values

In Haskell, you have type level programming and then value level programming.

plusTwo :: Integer -> Integer   -- Types 
 plusTwo x = x + 2               -- Values 

You do not mix types and values in Haskell like the below

plusTwo 2          -- This is valid 
 plusTwo Integer    -- This is not valid 

In Perl 6, types (AKA type objects) live on the same level as values

sub plus-two(Int $x --> Int) { $x + 2 } 
 
 plus-two(2);    # This is valid 
 plus-two(Int);  # This is valid 

I will illustrate this unique aspect of Perl 6 with one more example:

multi sub is-string(Str $ --> True) {} 
 multi sub is-string(Any $ --> False) {} 
 
 is-string('hello');    #True 
 is-string(4);          #False 

Maybe

In Haskell, you have a Maybe type that allows you to forgo the worry of null types. Let's say you have a hypothetical function that parses a String to an Integer:

parseInt :: String -> Maybe Integer 
 
 case parseInt myString of 
   Just x  -> x 
   Nothing -> 0 

In Perl 6, since type objects coexist with regular objects, we have the concept of Defined and Undefined objects. Plain type objects are undefined while instantiated objects are defined.

sub parse-int(Str $s --> Int) { ... } 
 
 my $string = {...}; 
 given parse-int($string) { 
   when Int:D { $_ } 
   when Int:U { 0 } 
 } 

So in Perl 6 we have type constraints that indicate the definedness of a type. These are

Int:D; # This is a defined Int. 
 Int:U; # This is an undefined Int, AKA a type object 
 Int:_; # This is either defined or undefined. 

If we wanted to be explicit in the above example (probably a good idea), we could add the :_ constraint on the return type. This would let the user know that they should account for both defined and undefined return values. We could also use other methods and constructs that specifically test for definedness.

sub parse-int(Str $s --> Int:_) { ... } 
 
 # One way to do it 
 my $string = {...}; 
 given parse-int($string) { 
   when Int:D { $_ } 
   when Int:U { 0 } 
 } 
 
 # Another way to do it 
 my Int $number = parse-int($string); 
 if $number.defined { $number } else { 0 } 
 
 
 # A better way 
 with parse-int($string) { $_ } else { 0 } 
 
 # With the defined-or operator 
 parse-int($string) // 0 

The with operator that you see above is like if, except it explicitly tests for definedness and then passes the result to the following block. Similarly, without tests that the object is undefined and also passes the result to the following block.

For more natural control flow with undefined and defined types, Perl 6 introduces andthen and orelse.

sub parse-int(Str $s --> Int:_) { ... } 
 
 my $string = {...}; 
 my $result = parse-int($string) orelse 0; 
 
 sub hello() { say 'hi' } 
 hello() andthen say 'bye'; 

TODO: include a better example for andthen that makes sense. Maybe using promise objects?

So in practice, Perl 6 does not have the concept of a null type, but rather of defined or undefined types.

Data Definitions

Perl 6 is fundamentally an Object Oriented language. However, it also gives you the freedom to write in virtually any paradigm you wish. If you only want to pure functions that take an object and return a new object, you can certainly do so.

Here is a Haskell code example:

data Point = Point x y 
 
 moveUp :: Point -> Point 
 moveUp (Point x y) = Point x (y + 1) 

And an equivalent Perl 6 example:

class Point { has $.x; has $.y; } 
 
 sub move-up(Point $p --> Point) { 
   Point.new(x => $p.x, y => $p.y + 1) 
 } 

The code I illustrated above is an example of a Product Type. If instead you'd like to write a Sum Type, there is not an exact equivalent in Perl 6. The closest thing would be an Enum.

data Animal = Dog | Cat | Bird | Horse 
 
 testAnimal :: Animal -> String 
 testAnimal Dog   = "Woof" 
 testAnimal Horse = "Neigh" 

A Perl 6 Enum does not fit the same exact use cases, but it can be used in putting constraints on types.

enum Animal < Dog Cat Bird Horse >; 
 
 proto sub test-animal( Animal        ) {*} 
 multi sub test-animal( Dog           ) { 'Woof' } 
 multi sub test-animal( Animal::Horse ) { 'Neigh'  }   # more explicit 
 
 say test-animal Animal::Dog; # more explicit 
 say test-animal Horse; 

Type Aliases and Subsets

In Haskell, you can alias an existing type to simply increase clarity of intent and re-use existing types.

type Name = String 
 
 fullName :: Name -> Name -> Name 
 fullName first last = first ++ last 

The equivalent in Perl 6 is the following.

my constant Name = Str; 
 
 sub full-name ( Name \first, Name \last --> Name ) { first ~ last } 

It should be noted that in Perl 6, one can also create a subset of an existing type.

subset Name of Str where *.chars < 20; 
 
 sub full-name(Name $first, Name $last) { 
   $first ~ $last 
 } 
 
 full-name("12345678901234567890111", "Smith") # This does not compile, as the first parameter 
                                               # doesn't fit the Name type 

Typeclasses

TODO

explain how Perl 6 roles compare to Haskell typeclasses

Functions

Definitions and Signatures

Matching

Haskell makes heavy use of pattern matching in function definitions.

greeting :: String -> String 
 greeting  ""   = "Hello, World!" 
 greeting "bub" = "Hey bub." 
 greeting  name = "Hello, " ++ name ++ "!" 

Perl 6 does this as well! You just use the multi keyword to signify that it is a multiple dispatch function.

proto greeting ( Str   --> Str ) {*} 
 multi greeting ( ""    --> "Hello, World!" ) {} 
 multi greeting ( "bub" --> "Hey bub." ) {} 
 multi greeting ( \name ) { "Hello, " ~ name ~ "!" } 

The proto declarator is not necessary, but can sometimes aid in making sure that all multis follow your business rules. Using a variable name in the signature of the proto would provide more information in error messages, and for introspection.

proto greeting ( Str \name --> Str ) {*} 
 
 say &greeting.signature;                  # (Str \name --> Str) 

An interesting thing to note in the Perl 6 code above is that passing values like 'bub' as a function parameter is just syntax sugar for a where guard.

Using the example from the "Pattern Matching" section of this page, you can see the guards that are used behind the scenes to constrain our function arguments.

multi greeting ( ""    --> "Hello, World!" ) {} 
 multi greeting ( "bub" --> "Hey bub." ) {} 
 
 # The above is the same as the below 
 
 multi greeting(Str \name where ''    ) {'Hello, World!'} 
 multi greeting(Str \name where 'bub' ) {'Hey bub.'} 
 
 # The above is the same as the below, again. 
 
 multi greeting(Str \name where $_ ~~ ''   ) {'Hello, World!'} 
 multi greeting(Str \name where $_ ~~ 'bub') {'Hey bub.'} 

$_ is known as the topic variable. It assumes the form of whatever is appropriate. The smartmatch operator ~~ figures out the best way to determine if the left matches the right, be it number ranges, strings, etc. Our three examples above go from most sugared (top), to least sugared (bottom).

The bottom examples above could be wrapped in curly braces, making it more obvious that it is a code block. Note that a where clause may also take an explicit Callable.

multi greeting(Str \name where { $_ ~~ '' } ) {'Hello, World!'} 
 
 multi greeting(Str \name where -> $thing { $thing ~~ '' } ) {'Hello, World!'} 
 
 multi greeting ( Str \name where { Bool.pick } --> 'True' ){} 
 
 multi greeting ( Str \name where &some-subroutine ){…} 

If you read the section in this page on subsets, you'll notice that "where" is used in the making of subsets as well as here. The usage of "where" in both areas is exactly the same.

When using where, note that the order of definition is important, just like in Haskell.

multi greeting ( Str \name where '' --> 'Hello, World!' ){} 
 multi greeting ( Str \name where { Bool.pick } --> 'True' ){} 
 multi greeting ( Str \name where 'bub' --> 'Hey, bub.' ){} 
 
 say greeting ''   ; # will never say True 
 say greeting 'bub'; # about 50% of the time it will say True 

Deconstruction

TODO

Currying

TODO

.assuming vs currying

method chaining vs currying

Composing

TODO

show function composition operator. Maybe explain a more perl6ish way to do this though.

Case / Matching

Haskell makes heavy use of case matching like the below:

case number of 
   2 -> "two" 
   4 -> "four" 
   8 -> "eight" 
   _ -> "don't care" 

In Perl 6 you can achieve this same thing with the given/when structure:

my $number = {...}; 
 given $number { 
   when 2  { "two" } 
   when 4  { "four" } 
   when 8  { "eight" } 
   default { "don't care" } 
 } 

Note that the order of the when's is also significant, just like with the where's in the guard section of this page.

Lists

TODO

explain difference between perl6 Array, Sequence, List. Explain data shapes in regards to the @ sigil. Explain how you can convert an Array to a flattened list of objects with |@

data shapes become quite intuitive, but it takes a bit of practice.

List Comprehensions

There are no explicit list comprehensions in Perl6. But rather, you can achieve list comprehensions a couple of different ways.

Here is a trivial example in Haskell:

evens = [ x | x <- [0..100], even x ] 

And now in Perl6 :

# using `if` and `for` 
 my @evens = ($_ if $_ %% 2 for 0..100); 
 
 # using gather/take to build a Seq 
 my $evens = gather for 0..100 { take $_ if $_ %% 2 }; 
 
 # using gather/take to build an Array 
 my @evens = gather for 0..100 { take $_ if $_ %% 2 }; 

Since for is always eager it is generally better to use map or grep which will inherit the laziness or eagerness of its list argument.

my @evens = map { $_ if $_ %% 2 }, 0..100; 
 
 my @evens = grep { $_ %% 2 }, 0..100; 
 
 # using a Whatever lambda 
 my @evens = grep  * %% 2,  0..100; 

Here is the creation of tuples in Haskell:

tuples = [(i,j) | i <- [1,2], 
                   j <- [1..4] ] 
 -- [(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4)] 

And in Perl6:

my @tuples = 1,2  X  1..4; 
 # [(1,1), (1,2), (1,3), (1,4), (2,1), (2,2), (2,3), (2,4)] 

See this design document for more information on what kinds of list comprehensions are possible in Perl6: http://design.perl6.org/S04.html#The_do-once_loop.

As you can see, when you get into some more advanced Haskell list comprehensions, Perl6 does not translate exactly the same, but it's possible to do the same things, nonetheless.

Fold

Fold in Haskell is called Reduce in Perl 6.

mySum = foldl `+` 0 numList 
my @numbers = {...}; 
 reduce { $^a + $^b }, 0, |@numbers; 
 @numbers.reduce({$^a + $^b}, with => 0) 

However, in Perl 6, if you want to use an infix operator (+ - / % etc) there is a nice little helper called the Reduction metaoperator.

my @numbers = {...}; 
 [+] @numbers    # This is the same 
 [+] 0, @numbers # as this 

It inserts the operator in between all values in the list and produces a result, just like Fold.

In Haskell you, you have foldl and foldr. In Perl 6, this difference is determined by the associativity attached to the operator/subroutine.

sub two-elem-list ( \a, \b ) { ( a, b ) } 
 
 # you can use a subroutine as an infix operator 
 say 'a' [&two-elem-list] 'b'; # (a b) 
 
 # as the reduction prefix metaoperator takes an infix operator, it will work there too; 
 [[&two-elem-list]] 1..5;           # ((((1 2) 3) 4) 5) 
 say (1..5).reduce: &two-elem-list; # ((((1 2) 3) 4) 5) 
 
 # right associative 
 sub right-two-elem-list( \a, \b ) is assoc<right> { ( a, b ) } 
 say (1..5).reduce: &right-two-elem-list; # (1 (2 (3 (4 5)))) 
 
 # XXX there is possibly a bug here as this currently doesn't look at 
 # XXX the associativity of &right-two-elem-list and just always does left assoc 
 say [[&right-two-elem-list]] 1..5; 
 
 # chaining 
 say [<] 1..5;            # True 
 say (1..5).reduce: &[<]; # True 

Map

TODO

Ranges

Haskell and Perl 6 both allow you to specify ranges of values.

myRange1 = 10..100 
 myRange2 = 1..        -- Infinite 
 myRange3 = 'a'..'h'   -- Letters work too 
my $range1 = 10..100; 
 my $range2 = 1..*;      # Infinite 
 my $range3 = 'a'..'h';  # Letters work too 

Laziness vs Eagerness

In the examples above, you have the concept of laziness displayed very plainly. Perl 6 has laziness only where it makes the most sense. For example, in the range 10..100, this is eager because it has a definite end. If a list does not have a definite end, then the list should clearly be lazy.

(1 .. 100).is-lazy; # False 
 (1 .. Inf).is-lazy; # True 

These are the "sane defaults" that Perl 6 takes pride in. But they are still defaults and can be changed into one or the other.

(1 .. 100).lazy.is-lazy;       # True 
 (1 .. 100).lazy.eager.is-lazy; # False 

Contexts (let-in / where)

TODO

explain how given/when and with/without and for loops open lexical scopes with the argument as the context.

compare it to let/in and where constructs maybe?

Parsers

Parser Combinators vs Grammars

TODO

25 Input/Output The Definitive Guide

Correctly use Perl 6 IO

The Basics

The vast majority of common IO work is done by the IO::Path type. If you want to read from or write to a file in some form or shape, this is the class you want. It abstracts away the details of filehandles (or "file descriptors") and so you mostly don't even have to think about them.

Behind the scenes, IO::Path works with IO::Handle; a class which you can use directly if you need a bit more control than what IO::Path provides. When working with other processes, e.g. via Proc or Proc::Async types, you'll also be dealing with a subclass of IO::Handle: the IO::Pipe.

Lastly, you have the IO::CatHandle, as well as IO::Spec and its subclasses, that you'll rarely, if ever, use directly. These classes give you advanced features, such as operating on multiple files as one handle, or low-level path manipulations.

Along with all these classes, Perl 6 provides several subroutines that let you indirectly work with these classes. These come in handy if you like functional programming style or in Perl 6 one liners.

While IO::Socket and its subclasses also have to do with Input and Output, this guide does not cover them.

Navigating Paths

What's an IO::Path Anyway?

To represent paths as either files or directories, use IO::Path type. The simplest way to obtain an object of that type is to coerce a Str by calling .IO method on it:

say 'my-file.txt'.IO; # OUTPUT: «"my-file.txt".IO␤»

It may seem like something is missing here—there is no volume or absolute path involved—but that information is actually present in the object. You can see it by using .perl method:

say 'my-file.txt'.IO.perl;
# OUTPUT: «IO::Path.new("my-file.txt", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))␤»

The two extra attributes—SPEC and CWD—specify what type of operating system semantics the path should use as well as the "current working directory" for the path, i.e. if it's a relative path, then it's relative to that directory.

This means that regardless of how you made one, an IO::Path object technically always refers to an absolute path. This is why its .absolute and .relative methods return Str objects and they are the correct way to stringify a path.

However, don't be in a rush to stringify anything. Pass paths around as IO::Path objects. All the routines that operate on paths can handle them, so there's no need to convert them.

Working with Files

Writing into files

Writing new content

Let's make some files and write and read data from them! The spurt and slurp routines write and read the data in one chunk. Unless you're working with very large files that are difficult to store entirely in memory all at the same time, these two routines are for you.

"my-file.txt".IO.spurt: "I ♥ Perl!"; 

The code above creates a file named my-file.txt in the current directory and then writes text I ♥ Perl! into it. If Perl 6 is your first language, celebrate your accomplishment! Try to open the file you created with some other program to verify what you wrote with your program. If you already know some other language, you may be wondering if this guide missed anything like handling encoding or error conditions.

However, that is all the code you need. The string will be encoded in utf-8 encoding by default and the errors are handled via the Failure mechanism: these are exceptions you can handle using regular conditionals. In this case, we're letting all potential Failures get sunk after the call and so any Exceptions they contain will be thrown.

Appending content

If you wanted to add more content to the file we made in previous section, you could note the spurt documentation mentions :append argument. However, for finer control, let's get ourselves an IO::Handle to work with:

my $fh = 'my-file.txt'.IO.open: :a; 
 $fh.print: "I count: "; 
 $fh.print: "$_ " for ^10; 
 $fh.close; 

The .open method call opens our IO::Path and returns an IO::Handle. We passed :a as argument, to indicate we want to open the file for writing in append mode.

In the next two lines of code, we use the usual .print method on that IO::Handle to print a line with 11 pieces of text (the 'I count: ' string and 10 numbers). Note that, once again, Failure mechanism takes care of all the error checking for us. If the .open fails, it returns a Failure, which will throw when we attempt to call method .print on it.

Finally, we close the IO::Handle by calling the .close method on it. It is important that you do it, especially in large programs or ones that deal with a lot of files, as many systems have limits to how many files a program can have open at the same time. If you don't close your handles, eventually you'll reach that limit and the .open call will fail. Note that unlike some other languages, Perl 6 does not use reference counting, so the filehandles are NOT closed when the scope they're defined in is left. They will be closed only when they're garbage collected and failing to close the handles may cause your program to reach the file limit before the open handles get a chance to get garbage collected.

Reading from files

Using IO::Path

We've seen in previous sections that writing stuff to files is a single-line of code in Perl 6. Reading from them, is similarly easy:

say 'my-file.txt'.IO.slurp;        # OUTPUT: «I ♥ Perl!␤» 
 say 'my-file.txt'.IO.slurp: :bin;  # OUTPUT: «Buf[uint8]:0x<49 20 e2 99 a5 20 50 65 72 6c 21>␤» 

The .slurp method reads entire contents of the file and returns them as a single Str object, or as a Buf object, if binary mode was requested, by specifying :bin named argument.

Since slurping loads the entire file into memory, it's not ideal for working with huge files.

The IO::Path type offers two other handy methods: .words and .lines that lazily read the file in smaller chunks and return Seq objects that (by default) don't keep already-consumed values around.

Here's an example that finds lines in a text file that mention Perl and prints them out. Despite the file itself being too large to fit into available RAM, the program will not have any issues running, as the contents are processed in small chunks:

.say for '500-PetaByte-File.txt'.IO.lines.grep: *.contains: 'Perl'; 

Here's another example that prints the first 100 words from a file, without loading it entirely:

.say for '500-PetaByte-File.txt'.IO.words: 100 

Note that we did this by passing a limit argument to .words instead of, say, using a list indexing operation. The reason for that is there's still a filehandle in use under the hood, and until you fully consume the returned Seq, the handle will remain open. If nothing references the Seq, eventually the handle will get closed, during a garbage collection run, but in large programs that work with a lot of files, it's best to ensure all the handles get closed right away. So, you should always ensure the Seq from IO::Path's .words and .lines methods is fully reified; and the limit argument is there to help you with that.

Using IO::Handle

Of course, you can read from files using the IO::Handle type, which gives you a lot finer control over what you're doing:

given 'some-file.txt'.IO.open { 
     say .readchars: 8;  # OUTPUT: «I ♥ Perl␤» 
     .seek: 1, SeekFromCurrent; 
     say .readchars: 15;  # OUTPUT: «I ♥ Programming␤» 
     .close 
 } 

The IO::Handle gives you .read, .readchars, .get, .getc, .words, .lines, .slurp, .comb, .split, and .Supply methods to read data from it. Plenty of options; and the catch is you need to close the handle when you're done with it.

Unlike some languages, the handle won't get automatically closed when the scope it's defined in is left. Instead, it'll remain open until it's garbage collected. To make the closing business easier, some of the methods let you specify a :close argument, you can also use the will leave trait, or the does auto-close trait provided by the Trait::IO module.

The Wrong Way To Do Things

This section describes how NOT to do Perl 6 IO.

Leave $*SPEC Alone

You may have heard of $*SPEC and seen some code or books show its usage for splitting and joining path fragments. Some of the routine names it provides may even look familiar to what you've used in other languages.

However, unless you're writing your own IO framework, you almost never need to use $*SPEC directly. $*SPEC provides low-level stuff and its use will not only make your code tough to read, you'll likely introduce security issues (e.g. null characters)!

The IO::Path type is the workhorse of Perl 6 world. It caters to all the path manipulation needs as well as provides shortcut routines that let you avoid dealing with filehandles. Use that instead of the $*SPEC stuff.

Tip: you can join path parts with / and feed them to IO::Path's routines; they'll still do The Right Thing™ with them, regardless of the operating system.

# WRONG!! TOO MUCH WORK! 
 my $fh = open $*SPEC.catpath: '', 'foo/bar', $file; 
 my $data = $fh.slurp; 
 $fh.close; 
# RIGHT! Use IO::Path to do all the dirty work 
 my $data = 'foo/bar'.IO.add($file).slurp; 

However, it's fine to use it for things not otherwise provided by IO::Path. For example, the .devnull method:

{ 
     temp $*OUT = open :w, $*SPEC.devnull; 
     say "In space no one can hear you scream!"; 
 } 
 say "Hello"; 

Stringifying IO::Path

Don't use the .Str method to stringify IO::Path objects, unless you just want to display them somewhere for information purposes or something. The .Str method returns whatever basic path string the IO::Path was instantiated with. It doesn't consider the value of the $.CWD attribute. For example, this code is broken:

# WRONG!! .Str DOES NOT USE $.CWD! 
 my $path = 'foo'.IO; 
 chdir 'bar'; 
 run <tar -cvvf archive.tar>, ~$path; 

The chdir call changed the value of the current directory, but the $path we created is relative to the directory before that change.

However, the IO::Path object does know what directory it's relative to. We just need to use .absolute or .relative to stringify the object. Both routines return a Str object; they only differ in whether the result is an absolute or relative path. So, we can fix our code like this:

# RIGHT!! .absolute does consider the value of $.CWD! 
 my $path = 'foo'.IO; 
 chdir 'bar'; 
 run <tar -cvvf archive.tar>, $path.absolute; 
 # Also good: 
 run <tar -cvvf archive.tar>, $path.relative; 

Be mindful of $*CWD

While usually out of view, every IO::Path object, by default, uses the current value of $*CWD to set its $.CWD attribute. This means there are two things to pay attention to.

temp the $*CWD

This code is a mistake:

# WRONG!! 
 my $*CWD = "foo".IO; 

The my $*CWD made $*CWD undefined. The .IO coercer then goes ahead and sets the $.CWD attribute of the path it's creating to the stringified version of the undefined $*CWD; an empty string.

The correct way to perform this operation is use temp instead of my. It'll localize the effect of changes to $*CWD, just like my would, but it won't make it undefined, so the .IO coercer will still get the correct old value:

temp $*CWD = "foo".IO; 

Better yet, if you want to perform some code in a localized $*CWD, use the indir routine for that purpose.

26 Input/Output

File-related operations

Here we present a quick overview of the file-related input/output operations. Details can be found in the documentation for the IO role, as well as the IO::Handle and IO::Path types.

Reading from files

One way to read the contents of a file is to open the file via the open function with the :r (read) file mode option and slurp in the contents:

my $fh = open "testfile", :r; 
 my $contents = $fh.slurp-rest; 
 $fh.close; 

Here we explicitly close the filehandle using the close method on the IO::Handle object. This is a very traditional way of reading the contents of a file. However, the same can be done more easily and clearly like so:

my $contents = "testfile".IO.slurp; 
 # or in procedural form: 
 $contents = slurp "testfile" 

By adding the IO role to the file name string, we are effectively able to refer to the string as the file object itself and thus slurp in its contents directly. Note that the slurp takes care of opening and closing the file for you.

Line by line

Of course, we also have the option to read a file line-by-line. The new line separator (i.e., $*IN.nl-in) will be excluded.

for 'huge-csv'.IO.lines -> $line { 
     # Do something with $line 
 } 
 
 # or if you'll be processing later 
 my @lines = 'huge-csv'.IO.lines; 

Writing to files

To write data to a file, again we have the choice of the traditional method of calling the open function – this time with the :w (write) option -- and printing the data to the file:

my $fh = open "testfile", :w; 
 $fh.print("data and stuff\n"); 
 $fh.close; 

Or equivalently with say, thus the explicit newline is no longer necessary:

my $fh = open "testfile", :w; 
 $fh.say("data and stuff"); 
 $fh.close; 

We can simplify this by using spurt to open the file in write mode, writing the data to the file and closing it again for us:

spurt "testfile", "data and stuff\n"; 

By default all (text) files are written as UTF-8, however if necessary, an explicit encoding can be specified via the :enc option:

spurt "testfile", "latin1 text: äöüß", enc => "latin1"; 

To write formatted strings to a file, use the printf function of IO::Handle.

my $fh = open "testfile", :w; 
 $fh.printf("formatted data %04d\n", 42); 
 $fh.close; 

To append to a file, specify the :a option when opening the filehandle explicitly,

my $fh = open "testfile", :a; 
 $fh.print("more data\n"); 
 $fh.close; 

or equivalently with say, thus the explicit newline is no longer necessary,

my $fh = open "testfile", :a; 
 $fh.say("more data"); 
 $fh.close; 

or even simpler with the :append option in the call to spurt:

spurt "testfile", "more data\n", :append; 

To explicitly write binary data to a file, open it with the :bin option. The input/output operations then will take place using the Buf type instead of the Str type.

Copying and renaming files

Routines copy, rename, and move are available to avoid low-level system commands. See details at copy, rename, and move. Some examples:

my $filea = 'foo'; 
 my $fileb = 'foo.bak'; 
 my $filec = '/disk1/foo';  # note 'diskN' is assumed to be a physical storage device 
 
 copy $filea, $fileb;              # overwrites $fileb if it exists 
 copy $filea, $fileb, :createonly; # fails if $fileb exists 
 
 rename $filea, 'new-foo';              # overwrites 'new-foo' if it exists 
 rename $filea, 'new-foo', :createonly; # fails if 'new-foo' exists 
 
 # use move when a system-level rename may not work 
 move $fileb, '/disk2/foo';              # overwrites '/disk2/foo' if it exists 
 move $fileb, '/disk2/foo', :createonly; # fails if '/disk2/foo' exists 

Checking files and directories

Use the e method on an IO::Handle object to test whether the file or directory exists.

if "nonexistent_file".IO.e { 
     say "file exists"; 
 } 
 else { 
     say "file doesn't exist"; 
 } 

It is also possible to use the colon pair syntax to achieve the same thing:

if "path/to/file".IO ~~ :e { 
     say 'file exists'; 
 } 
my $file = "path/to/file";
if $file.IO ~~ :e {
    say 'file exists';
}

Similarly to the file existence check, one can also check to see if a path is a directory. For instance, assuming that the file testfile and the directory lib exist, we would obtain from the existence test method e the same result, namely that both exist:

say "testfile".IO.e;  # OUTPUT: «True␤» 
 say "lib".IO.e;       # OUTPUT: «True␤» 

However, since only one of them is a directory, the directory test method d will give a different result:

say "testfile".IO.d;  # OUTPUT: «False␤» 
 say "lib".IO.d;       # OUTPUT: «True␤» 

Naturally the tables are turned if we check to see if the path is a file via the file test method f:

say "testfile".IO.f;  # OUTPUT: «True␤» 
 say "lib".IO.f;       # OUTPUT: «False␤» 

There are other methods that can be used to query a file or directory, some useful ones are:

my $f = "file"; 
 
 say $f.IO.modified; # return time of last file (or directory) change 
 say $f.IO.accessed; # return last time file (or directory) was read 
 say $f.IO.s;        # return size of file (or directory inode) in bytes 

See more methods and details at IO::Path.

Getting a directory listing

To list the contents of the current directory, use the dir function. It returns a list of IO::Path objects.

say dir;          # OUTPUT: «"/path/to/testfile".IO "/path/to/lib".IO␤»

To list the files and directories in a given directory, simply pass a path as an argument to dir:

say dir "/etc/";  # OUTPUT: «"/etc/ld.so.conf".IO "/etc/shadow".IO ....␤»

Creating and removing directories

To create a new directory, simply call the mkdir function with the directory name as its argument:

mkdir "newdir"; 

The function returns the name of the created directory on success and Nil on failure. Thus the standard Perl idiom works as expected:

mkdir "newdir" or die "$!"; 

Use rmdir to remove empty directories:

rmdir "newdir" or die "$!"; 

27 Inter-Process Communication

Programs running other programs and communicating with them

running

Many programs need to be able to run other programs. Running a program in Perl 6 is as easy as:

run 'git', 'status';

This line runs the program named "git" and passes "git" and "status" to its command-line. It will find the program using the %*ENV<PATH> setting.

If you would like to run a program by sending a command-line to the shell, there's a tool for that as well. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on.

shell 'ls -lR | gzip -9 > ls-lR.gz';

Caution should be taken when using shell with user input.

proc

Both run and shell return a Proc object, which can be used to communicate with the process in more detail. Please note that unless you close all output pipes, the program will usually not terminate.

my $git = run 'git', 'log', '--oneline', :out;
for $git.out.lines -> $line {
    my ($sha, $subject) = $line.split: ' ', 2;
    say "$subject [$sha]";
}
$git.out.close();

If the program fails (exits with a non-zero exit code), it will throw an exception when the returned Proc object is sunk. You can save it into a variable, even anonymous one, to prevent the sinking:

$ = run '/bin/false'; # does not sink the Proc and so does not throw

You can tell the Proc object to capture output as a filehandle by passing the :out and :err flags. You may also pass input via the :in flag.

my $echo = run 'echo', 'Hello, world', :out;
my $cat  = run 'cat', '-n', :in($echo.out), :out;
say $cat.out.get;
$cat.out.close();

You may also use Proc to capture the PID, send signals to the application, and check the exitcode.

my $crontab = run 'crontab', '-l';
if $crontab.exitcode == 0 {
    say 'crontab -l ran ok';
}
else {
    say 'something went wrong';
}

async

When you need more control over the communication with and from another process, you will want to make use of Proc::Async. This class provides support for asynchronous communication with a program, as well as the ability to send signals to that program.

# Get ready to run the program 
 my $log = Proc::Async.new('tail', '-f',  '/var/log/system.log'); 
 $log.stdout.tap(-> $buf { print $buf }); 
 $log.stderr.tap(-> $buf { $*ERR.print($buf) }); 
 
 # Start the program 
 my $done = $log.start; 
 sleep 10; 
 
 # Tell the program to stop 
 $log.kill('QUIT'); 
 
 # Wait for the program to finish 
 await $done; 

Here is a small program that uses the "tail" program to print out the contents of the log named system.log for 10 seconds and then tells the program to stop with a QUIT signal.

Whereas Proc provides access to output using IO::Handles, Proc::Async provides access using asynchronous supplies (see Supply).

If you want to run a program and do some work while you wait for the original program to finish, the start routine returns a Promise, which is kept when the program quits.

Use the write method to pass data into the program.

28 Iterating

Functionalities available for visiting all items in a complex data structure

The Iterator and Iterable roles

Perl 6 is a functional language, but functions need something to hold on to when working on complex data structures. In particular, they need an uniform interface that can be applied to all of them. This interface is provided by the Iterator and Iterable roles.

The Iterable role is relatively simple. It provides a stub for the iterator method, which is the one actually used by statements such as for. for will call .iterator on the variable it precedes, and then run a block once for every item. Other methods, such as array assignment, will make the Iterable class behave in the same way.

class DNA does Iterable { 
     has $.chain; 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator(DNA:D:){ $.chain.comb.rotor(3).iterator } 
 }; 
 
 my @longer-chain =  DNA.new('ACGTACGTT'); 
 say @longer-chain.perl; 
 # OUTPUT: «[("A", "C", "G"), ("T", "A", "C"), ("G", "T", "T")]␤» 
 
 say  @longer-chain».join("").join("|"); #OUTPUT: «ACG|TAC|GTT␤» 

In this example, which is an extension of the example in Iterable that shows how for calls .iterator, this method is called simply when the created object is assigned to a Positional variable, @longer-chain; this variable is an Array and we operate on that in the last example.

The (maybe a bit confusingly named) Iterator role is a bit more complex than Iterable. First, it provides a constant, IterationEnd, but then it provides a series of methods such as .pull-one, which allows for a finer operation of iteration in several contexts: adding or eliminating items, or skipping over them to access other items. In fact, the role provides a default implementation for all the other methods, so the only one that has to be defined is precisely pull-one, of which only a stub is provided. While Iterable provides the high-level variable loops will be working in, Iterator provides the lower-level functions that will be called in every iteration of the loop. Let's extend the previous example with this role.

class DNA does Iterable does Iterator { 
     has $.chain; 
     has Int $!index = 0; 
 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator( ){ self } 
     method pull-one( --> Mu){ 
         if $!index < $.chain.chars { 
             my $codon = $.chain.comb.rotor(3)[$!index div 3]; 
             $!index += 3; 
             return $codon; 
         } else { 
             return IterationEnd; 
         } 
     } 
 }; 
 
 my $a := DNA.new('GAATCC'); 
 .say for $a; # OUTPUT: «(G A A)␤(T C C)␤» 

We declare a DNA class which does the two roles, Iterator and Iterable; the class will include a string that will be constrained to have a length that is a multiple of 3 and composed only of ACGT. Let us first look at the pull-one method. This one is going to be called every time a new iteration occurs, so it must keep the state of the last one. A $.index property will hold that state across invocations; pull-one will check if the end of the chain has been reached and will return the IterationEnd constant provided by the role. Implementing this low-level interface, in fact, simplifies the implementation of the Iterable interface. Now the iterator will be the object itself, since we can call pull-one on it to access every member in turn; .iterator will thus return just self; this is possible since the object will be, at the same time, Iterable and Iterator.

This need not always be the case, and in most cases .iterator will have to build an iterator type to be returned, such as we did in the previous example; however, this example shows the minimal code needed to build a class that fulfills the two iter(ator|able) roles.

How to iterate: contextualizing and topic variables

for and other loops place the item produced in every iteration into the topic variable $_, or capture them into the variables that are declared along with the block. These variables can be directly used inside the loop, without needing to declare them, by using the ^ twigil.

Implicit iteration occurs when using the sequence operator.

say 1,1,1, { $^a²+2*$^b+$^c } … * > 300; # OUTPUT: «(1 1 1 4 7 16 46 127 475)

The generating block is being run once while the condition to finish the sequence, in this case the term being bigger than 300, is not met. This has the side effect of running a loop, but also creating a list that is output.

This can be done more systematically through the use of the gather/take blocks, which are a different kind of iterating construct that instead of running in sink context, returns an item every iteration. This Advent Calendar tutorial explains use cases for this kind of loops; in fact, gather is not so much a looping construct, but a statement prefix that collects the items produced by take and creates a list out of them.

Classic loops and why we do not like them

Classic for loops, with a loop variable being incremented, can be done in Perl 6 through the loop keyword. Other repeat and while loops are also possible.

However, in general, they are discouraged. Perl 6 is a functional and concurrent language; when coding in Perl 6, you should look at loops in a functional way: processing, one by one, the items produced by an iterator, that is, feeding an item to a block without any kind of secondary effects. This functional view allows also easy parallelization of the operation via the hyper or race auto-threading methods.

If you feel more comfortable with your good old loops, the language allows you to use them. However, it is considered more p6y to try and use, whenever possible, functional and concurrent iterating constructs.

29 Javascript (Node) to Perl 6 - Nutshell

Learning Perl 6 from Node.js, in a nutshell

This page attempts to provide a way for users experienced in Node.js to learn Perl 6. Features shared between the two languages will be explained here, as well as major differences in syntax and features.

This is not a tutorial for learning Perl 6; this is a reference for users who are already at an intermediate to advanced skill level with Node.js.

Basic Syntax

"Hello, world!"

Let's start with the typical first program when learning new languages. In Node.js, a hello world program would be written like this:

console.log('Hello, world!'); 

Here are a couple ways to write this in the same way in Perl 6:

say('Hello, world!'); 
 say 'Hello, world!'; 

Parentheses are optional for function calls in Perl 6. While semicolons are, for the most part, optional in Node.js, they are mandatory for expressions in Perl 6.

Now that we've greeted the world, let's greet our good friend, Joe. We'll start with Node.js again:

let name = 'Joe'; 
 console.log('What\'s up,' + name + '?'); 
 console.log(`What's up, {name}?`); 
 console.log("What's up, ", name, "?"); 

Since he didn't hear us, let's greet him again, this time in Perl 6:

my $name = 'Joe'; 
 say 'What\'s up, ' ~ $name ~ '?'; 
 say "What's up, $name?"; 
 say "What's up, ", $name, "?"; 

Here, there are only a couple differences: most variables in Perl 6 have what are called sigils, which are what the $ in front of its name is, and string concatenation uses the ~ operator instead of +. What the two languages share in common here is support for string interpolation.

Now that the basic examples are out of the way, let's explain the similarities between the two languages in greater detail.

Variables

Variables in Node.js can be defined like this;

var foo = 1;    // Lexically scoped with functions and modules 
 let foo = 1;    // Lexically scoped with blocks 
 const foo = 1;  // Lexically scoped with blocks; constant 
 
 global.foo = 1; // Dynamically scoped; global 
 foo = 1;        // Ditto, but implicit; forbidden in strict mode 

In Perl 6 there is no equivalent to var. An important note to make is that there is no variable hoisting in Perl 6; variables are defined and assigned at the line they're on, not defined at the top of its scope and later assigned at that line.

This is how the equivalent types of variables are defined in Perl 6:

my $foo = 1;      # Lexically scoped with blocks 
 our $foo = 1;     # Lexically scoped with blocks and modules 
 constant foo = 1; # Lexically scoped with blocks and modules; constant 
 
 my $*foo = 1;       # Dynamically scoped with blocks 
 OUR::<$foo> = 1;    # Dynamically scoped with blocks and modules 
 GLOBAL::<$foo> = 1; # Dynamically scoped; global 

Use my where you'd use let, our for variables you'd define in the outermost scope needed, and constant where you'd uses const.

Dynamically scoped variables are not referred to in the same way as lexically scoped ones like they are in Node.js. User-defined ones use either a $*, @*, %*, or &* twigil. Refer to the documentation on variables for more information on sigils, twigils, and variable containers.

Variables in Node.js can override others from outer scopes with the same name (though linters will usually complain about it depending on how they're configured):

let foo = 1; 
 function logDupe() { 
     let foo = 2; 
     console.log(foo); 
 } 
 
 logDupe(2);       // 2 
 console.log(foo); // 1 

Perl 6 also allows this:

my $foo = 1; 
 sub log-dupe { 
     my $foo = 2; 
     say $foo; 
 } 
 
 log-dupe; # 2 
 say $foo; # 1 

Operators

Assignment

The = operator works the same across both languages.

The := operator in Perl 6 binds a value to a variable. Binding a variable to another variable gives them the same value and container, meaning mutating attributes of one will mutate the other's as well. Bound variables cannot be reassigned with = or mutated with ++, --, etc. but they can be bound to another value again:

my %map;            # This is a hash, roughly equivalent to a JS object or map 
 my %unbound = %map; 
 my %bound := %map; 
 %map<foo> = 'bar'; 
 say %unbound;       # {} 
 say %bound;         # {foo => bar} 
 
 %bound := %unbound; 
 say %bound;         # {} 

Equality

Node.js has two equality operators: == and ===.

== is the loose equality operator. When comparing operands with the same type, it will return true if both operands are equal. However, if the operands are different types, they are both cast to their primitives before being compared, meaning these will return true:

console.log(1 == 1);   // true 
 console.log('1' == 1); // true 
 console.log([] == 0);  // true 

Similarly, in Perl 6, both operands are cast to Numeric before comparison if they don't share the same type:

say 1 == 1;       # True 
 say '1' == 1;     # True 
 say [1,2,3] == 3; # True, since the array has three elements 

The inverse of == is !=.

Perl 6 has another operator similar to ==: eq. Instead of casting operands to Numeric if they're different types, eq will cast them to strings:

say '1' eq '1'; # True 
 say 1 eq '1';   # True 

The inverse of eq is ne or !eq.

=== is the strict equality operator. This returns true if both operands are the same value. When comparing objects, this will only return true if they are the exact same object:

console.log(1 === 1);   // true 
 console.log('1' === 1); // false 
 console.log({} === {}); // false 
 
 let obj = {}; 
 let obj2 = obj; 
 console.log(obj === obj2); // true; 

In Perl 6, the operator behaves the same, with one exception: two objects that have the same value, but different containers, will return false:

say 1 === 1; # True 
 say '1' === 1; # True 
 say {} === {};  # False 
 
 my \hash = {}; 
 my %hash := hash; 
 say hash === %hash; # False 

The inverse of === is !==.

This is where Perl 6's other equality operators are useful. If the values have different containers, the eqv operator can be used. This operator can be also be used to check for deep equality, which you would normally need to use a library for in Node.js:

say {a => 1} eqv {a => 1}; # True; 
 
 my \hash = {}; 
 my %hash := hash; 
 say hash eqv %hash; # True 

In the case you need to check if two variables have the same container and value, use the =:= operator.

my @arr = [1,2,3]; 
 my @arr2 := @arr;   # Bound variables keep the container of the other variable 
 say @arr =:= @arr2; # True 

Smartmatching

Perl 6 has one last operator for comparing values, but it is not exactly an equality operator. This is ~~, the smartmatch operator. This has several uses: it can be used like instanceof in Node.js, to match a regex, and to check if a value is a key in a hash, bag, set, or map:

say 'foo' ~~ Str; # True 
 
 my %hash = a => 1; 
 say 'a' ~~ %hash; # True 
 
 my $str = 'abc'; 
 $str ~~ s/abc/def/; # Mutates $str, like foo.replace('abc', 'def') 
 say $str;           # def 

While we are talking about instanceof, the equivalent to typeof or the constructor property on Node.js objects in Perl 6 is the ^name meta-attribute:

console.log(typeof 'foo');      // string 
 console.log('foo'.constructor); // String 
say 'foo'.^name; # Str 

Numeric

Node.js has +, -, /, *, %, and (in ES6) ** as numeric operators. When the operands are different types, similarly to the equality operators, are cast to their primitives before following through with the operation, making this possible:

console.log(1 + 2);   // 3 
 console.log([] + {}); // [object Object] 
 console.log({} + []); // 0 

In Perl 6, again, they are converted to a Numeric type, as before:

say 1 + 2;        # 3 
 say [] + {};      # 0 
 say {} + [1,2,3]; # 3 

In addition, Perl 6 has div and %%. div behaves like int division in C, while %% checks if one number is cleanly divisible by another or not:

say 4 div 3; # 1 
 say 4 %% 3;  # False 
 say 6 %% 3;  # True 

Bitwise

Node.js has &, |, ^, ~, <<, >>, >>>, and ~ for bitwise operators:

console.log(1 << 1);  // 2 
 console.log(1 >> 1);  // 0 
 console.log(1 >>> 1); // 0 
 console.log(1 & 1);   // 1 
 console.log(0 | 1);   // 1 
 console.log(1 ^ 1);   // 0 
 console.log(~1);      // -2 

In Perl 6, there is no equivalent to >>>. All bitwise operators are prefixed with +, however two's complement uses +^ instead of ~:

say 1 +< 1; # 2 
 say 1 +> 1; # 0 
             # No equivalent for >>> 
 say 1 +& 1; # 1 
 say 0 +| 1; # 1 
 say 1 +^ 1; # 0 
 say +^1;    # -2 

Custom Operators and Operator Overloading

Node.js does not allow operator overloading without having to use a Makefile or build Node.js with a custom version of V8. Perl 6 allows custom operators and operator overloading natively! Since all operators are subroutines, you can define your own like so:

multi sub infix:<||=>($a, $b) is equiv(&infix:<+=>) { $a || $b } 
 
 my $foo = 0; 
 $foo ||= 1; 
 say $foo; # 1 

Operators can be defined as prefix, infix, or postfix. The is tighter, is equiv, and is looser traits optionally define the operator's precedence. In this case, ||= has the same precedence as +=.

Note how multi is used when declaring the operator subroutines. This allows multiple subroutines with the same name to be declared while also having different signatures. This will be explained in greater detail in the Functions section. For now, all we need to know is that it allows us to override any native operator we want:

# Using the `is default` trait here forces this subroutine to be chosen first, 
 # so long as the signature of the subroutine matches. 
 multi sub prefix:<++>($a) is default { $a - 1 } 
 
 my $foo = 1; 
 say ++$foo; # 0 

Conditionals

TODO

# TBD

Control Flow

TODO

# TBD

Functions

TODO

# TBD

Types

TODO

# TBD

Object-Oriented Programming

TODO

# TBD

The Networking API

TODO

# TBD

The Filesystem API

TODO

# TBD

Modules and Packages

TODO

# TBD

30 Lists, Sequences, and Arrays

Positional data constructs

Lists have been a central part of computing since before there were computers, during which time many devils have taken up residence in their details. They were actually one of the hardest parts of Perl 6 to design, but through persistence and patience, Perl 6 has arrived with an elegant system for handling them.

Literal Lists

Literal List s are created with commas and semicolons not with parentheses, so:

1, 2;                # This is two-element list
our $list = (1, 2);  # This is also a List, in parentheses
$list = (1; 2);      # same List (see below)
$list = (1);         # This is not a List, just a 1 in parentheses
$list = (1,);        # This is a one-element List

There is one exception, empty lists are created with just parenthesis:

();          # This is an empty List 
 (,);         # This is a syntax error 

Note that hanging commas are just fine as long as the beginning and end of a list are clear, so feel free to use them for easy code editing.

Parentheses can be used to mark the beginning and end of a List, so:

(1, 2), (1, 2); # This is a list of two lists.

Lists of Lists can also be created by combining comma and semicolon. This is also called multi-dimensional syntax, because it is most often used to index multidimensional arrays.

say so (1,2; 3,4) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so (1,2; 3,4;) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so ("foo";) eqv ("foo") eqv (("foo")); # not a list
# OUTPUT: «True␤»

Unlike a comma, a hanging semicolon does not create a multidimensional list in a literal. However, be aware that this behavior changes in most argument lists, where the exact behavior depends on the function... but will usually be:

say('foo';);   # a list with one element and the empty list
# OUTPUT: «(foo)()␤»
say(('foo';)); # no list, just the string "foo"
# OUTPUT: «foo␤»

Because the semicolon doubles as a statement terminator it will end a literal list when used at the top level, instead creating a statement list. If you want to create a statement list inside parenthesis, use a sigil before the parenthesis:

say so (42) eqv $(my $a = 42; $a;);
# OUTPUT: «True␤»
say so (42,42) eqv (my $a = 42; $a;);
# OUTPUT: «True␤»

Individual elements can be pulled out of a list using a subscript. The first element of a list is at index number zero:

say (1, 2)[0];  # says 1 
 say (1, 2)[1];  # says 2 
 say (1, 2)[2];  # says Nil 
 say (1, 2)[-1]; # Error 
 say ((<a b>,<c d>),(<e f>,<g h>))[1;0;1]; # says "f" 

The @ sigil

Variables in Perl 6 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.

By default, when you assign a List to an @-sigiled variable, you create an Array. Those are described below. If instead you want to refer directly to a List object using an @-sigiled variable, you can use binding with := instead.

my @a := 1, 2, 3;

One of the ways @-sigiled variables act like lists is by always supporting positional subscripting. Anything bound to a @-sigiled value must support the Positional role which guarantees that this is going to fail:

my @a := 1; # Type check failed in binding; expected Positional but got Int

Reset a List Container

To remove all elements from a Positional container assign Empty, the empty list () or a Slip of the empty list to the container.

my @a = 1, 2, 3;
@a = ();
@a = Empty;
@a = |();

Iteration

All lists may be iterated, which means taking each element from the list in order and stopping after the last element:

for 1, 2, 3 { .say }  # OUTPUT: «1␤2␤3␤»

Single Argument Rule

It is the rule by which the set of parameters passed to an iterator such as for is treated as a single argument, instead of several arguments; that is some-iterator( a, b, c, ...) will always be treated as some-iterator( list-or-array(a, b, c)) and never as (some-iterator(a))(b)..., that is, iterative application of the iterator to the first argument, then the result to the next argument, and so on. In this example

my @list = [ (1, 2, 3), 
              (1, 2, ), 
              [<a b c>, <d e f>], 
              [[1]] ]; 
 
 for @list -> @element { 
   say "{@element} → {@element.^name}"; 
     for @element -> $sub-element { 
       say $sub-element; 
     } 
 } 
 # OUTPUT 
 #1 2 3 → List 
 #1 
 #2 
 #3 
 #1 2 → List 
 #1 
 #2 
 #a b c d e f → Array 
 #(a b c) 
 #(d e f) 
 #1 → Array 
 #1 

Since what for receives is a single argument, it will be treated as a list of elements to iterate over. The rule of thumb is that if there's a comma, anything preceding it is an element and the list thus created becomes the single element. That happens in the case of the two arrays separated by a comma which are the third in the Array we are iterating. In general, quoting the article linked above, the single argument rule ... makes for behave as the programmer would expect.

Testing for Elements

To test for elements in a List or Array, you can use the "is element of" Set operator.

my @a = <foo bar buzz>;
say 'bar' (elem) @a;    # OUTPUT: «True␤»
say 'bar' ∈ @a;         # same, using unicode version of operator

This is the equivalent of:

    'bar' (elem) @a.Set;    # convert the array to a Set first 

except that, if possible, it won't actually do the conversion.

It basically compares the value with each element in the array using the === infix operator. If you want to use another way to compare values, you probably should use first.

Sequences

Not all lists are born full of elements. Some only create as many elements as they are asked for. These are called sequences, which are of type Seq. As it so happens, loops return Seqs.

(loop { 42.say })[2]  # OUTPUT: «42␤42␤42␤»

So, it is fine to have infinite lists in Perl 6, just so long as you never ask them for all their elements. In some cases, you may want to avoid asking them how long they are too – Perl 6 will try to return Inf if it knows a sequence is infinite, but it cannot always know.

These lists can be built using the ... operator, which builds lazy lists using a variety of generating expressions.

Although the Seq class does provide some positional subscripting, it does not provide the full interface of Positional, so an @-sigiled variable may not be bound to a Seq, and trying to do so will yield an error.

my @s := <a b c>.Seq; CATCH { default { say .^name, ' ', .Str } }
# OUTPUT «X::TypeCheck::Binding Type check failed in binding; expected Positional but got Seq ($(("a", "b","c").Seq))␤»

This is because the Seq does not keep values around after you have used them. This is useful behavior if you have a very long sequence, as you may want to throw values away after using them, so that your program does not fill up memory. For example, when processing a file of a million lines:

for 'filename'.IO.lines -> $line { 
     do-something-with($line); 
 } 

You can be confident that the entire content of the file will not stay around in memory, unless you are explicitly storing the lines somewhere.

On the other hand, you may want to keep old values around in some cases. It is possible to hide a Seq inside a List, which will still be lazy, but will remember old values. This is done by calling the .list method. Since this List fully supports Positional, you may bind it directly to an @-sigiled variable.

my @s := (loop { 42.say }).list;
@s[2]; # says 42 three times
@s[1]; # does not say anything
@s[4]; # says 42 two more times

You may also use the .cache method instead of .list, depending on how you want the references handled. See the page on Seq for details.

TODO document .iterator

Slips

Sometimes you want to insert the elements of a list into another list. This can be done with a special type of list called a Slip.

say (1, (2, 3), 4) eqv (1, 2, 3, 4);         # OUTPUT: «False␤»
say (1, Slip.new(2, 3), 4) eqv (1, 2, 3, 4); # OUTPUT: «True␤»
say (1, slip(2, 3), 4) eqv (1, 2, 3, 4);     # OUTPUT: «True␤»

Another way to make a Slip is with the | prefix operator. Note that this has a tighter precedence than the comma, so it only affects a single value, but unlike the above options, it will break Scalars.

say (1, |(2, 3), 4) eqv (1, 2, 3, 4);        # OUTPUT: «True␤»
say (1, |$(2, 3), 4) eqv (1, 2, 3, 4);       # OUTPUT: «True␤»
say (1, slip($(2, 3)), 4) eqv (1, 2, 3, 4);  # OUTPUT: «False␤»

Lazy lists

Lists, Seqs (and any class that subclasses them, like Arrays) and any other class thet implements the Iterable role can be lazy, which means that their values are computed on demand and stored for later use. To create a lazy object use gather/take or the sequence operator. You can also write a class that implements the role Iterator and returns True on a call to is-lazy. Please note that some methods like elems cannot be called on a lazy List and will result in a thrown Exception.

# This array is lazy and its elements will not be available
# until explicitly requested.

my @lazy-array = lazy 1, 11, 121 ... 10**100;
say @lazy-array.is-lazy;     # OUTPUT: «True␤»
say @lazy-array[];           # OUTPUT: «[...]␤»

# Once all elements have been retrieved, the List
# is no longer considered lazy.

my @no-longer-lazy = eager @lazy-array;  # Forcing eager evaluation
say @no-longer-lazy.is-lazy;             # OUTPUT: «False␤»
say @no-longer-lazy[];
# OUTPUT: (sequence starting with «[1 11 121» ending with a 300 digit number)

In the example above, @lazy-array is an Array which, through construction, is made lazy. Calling is-lazy on it returns an Iterator, which, since it originates in a lazy list, is itself lazy.

A common use case for lazy Seqs is the processing of infinite sequences of numbers, whose values have not been computed yet and cannot be computed in their entirety. Specific values in the List will only be computed when they are needed.

my  $l := 1, 2, 4, 8 ... Inf;
say $l[0..16];
# OUTPUT: «(1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536)␤»

You can easily assign lazy objects to other objects, conserving their laziness:

my  $l := 1, 2, 4, 8 ... Inf; # This is a lazy Seq.
my  @lazy-array = $l;
say @lazy-array[10..15]; # OUTPUT: «(1024 2048 4096 8192 16384 32768)␤»
say @lazy-array.is-lazy; # OUTPUT: «True␤»

Immutability

The lists we have talked about so far (List, Seq and Slip) are all immutable. This means you cannot remove elements from them, or re-bind existing elements:

(1, 2, 3)[0]:delete; # Error Can not 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 

However, if any of the elements is wrapped in a Scalar you can still change the value which that Scalar points to:

my $a = 2;
(1, $a, 3)[1] = 42;
$a.say;            # OUTPUT: «42␤»

that is, it is only the list structure itself – how many elements there are and each element's identity – that is immutable. The immutability is not contagious past the identity of the element.

List Contexts

So far we have mostly dealt with lists in neutral contexts. Lists are actually very context sensitive on a syntactical level.

List Assignment Context

When a list appears on the right-hand side of an assignment into a @-sigiled variable, it is "eagerly" evaluated. This means that a Seq will be iterated until it can produce no more elements. This is one of the places you do not want to put an infinite list, lest your program hang and, eventually, run out of memory:

my $i = 3;
my @a = (loop { $i.say; last unless --$i }); # OUTPUT: «3␤2␤1␤»
say "take off!";

Flattening "Context"

When you have a list that contains sub-lists, but you only want one flat list, you may flatten the list to produce a sequence of values as if all parentheses were removed. This works no matter how many levels deep the parentheses are nested.

say (1, (2, (3, 4)), 5).flat eqv (1, 2, 3, 4, 5) # OUTPUT: «True␤»

This is not really a syntactical "context" as much as it is a process of iteration, but it has the appearance of a context.

Note that Scalar s around a list will make it immune to flattening:

for (1, (2, $(3, 4)), 5).flat { .say } # OUTPUT: «1␤2␤(3 4)␤5␤»

...but an @-sigiled variable will spill its elements.

my @l := 2, (3, 4);
for (1, @l, 5).flat { .say };      # OUTPUT: «1␤2␤3␤4␤5␤»
my @a = 2, (3, 4);                 # Arrays are special, see below
for (1, @a, 5).flat { .say };      # OUTPUT: «1␤2␤(3 4)␤5␤»

Argument List (Capture) Context

When a list appears as arguments to a function or method call, special syntax rules are at play: the list is immediately converted into a Capture. A Capture itself has a List (.list) and a Hash (.hash). Any Pair literals whose keys are not quoted, or which are not parenthesized, never make it into .list. Instead, they are considered to be named arguments and squashed into .hash. See the page on Capture for the details of this processing.

Consider the following ways to make a new Array from a List. These ways place the List in an argument list context and because of that, the Array only contains 1 and 2 but not the Pair :c(3), which is ignored.

Array.new(1, 2, :c(3));
Array.new: 1, 2, :c(3);
new Array: 1, 2, :c(3);

In contrast, these ways do not place the List in argument list context, so all the elements, even the Pair :c(3), are placed in the Array.

Array.new((1, 2, :c(3)));
(1, 2, :c(3)).Array;
my @a = 1, 2, :c(3); Array.new(@a);
my @a = 1, 2, :c(3); Array.new: @a;
my @a = 1, 2, :c(3); new Array: @a;

In argument list context the | prefix operator applied to a Positional will always slip list elements as positional arguments to the Capture, while a | prefix operator applied to an Associative will slip pairs in as named parameters:

my @a := 2, "c" => 3;
Array.new(1, |@a, 4);    # Array contains 1, 2, :c(3), 4
my %a = "c" => 3;
Array.new(1, |%a, 4);    # Array contains 1, 4

Slice Indexing Context

From the perspective of the List inside a slice subscript, is only remarkable in that it is unremarkable: because adverbs to a slice are attached after the ], the inside of a slice is not an argument list, and no special processing of pair forms happens.

Most Positional types will enforce an integer coercion on each element of a slice index, so pairs appearing there will generate an error, anyway:

(1, 2, 3)[1, 2, :c(3)] # OUTPUT: «Method 'Int' not found for invocant of class 'Pair'␤» 

...however this is entirely up to the type – if it defines an order for pairs, it could consider :c(3) a valid index.

Indices inside a slice are usually not automatically flattened, but neither are sublists usually coerced to Int. Instead, the list structure is kept intact, causing a nested slice operation that replicates the structure in the result:

say ("a", "b", "c")[(1, 2), (0, 1)] eqv (("b", "c"), ("a", "b")) # OUTPUT: «True␤»

Slices can be taken also across several dimensions using semilists, which are lists of slices separated by semicolons:

my @sliceable = [[ ^10 ], ['a'..'h'], ['Ⅰ'..'Ⅺ']];
say @sliceable[ ^3; 4..6 ]; #OUTPUT: «(4 5 6 e f g Ⅴ Ⅵ Ⅶ)␤»

which is selecting the 4 to 6th element from the three first dimensions (^3).

Range as Slice

A Range is a container for a lower and a upper boundary. Generating a slice with a Range will include any index between those bounds, including the bounds. For infinite upper boundaries we agree with mathematicians that Inf equals Inf-1.

my @a = 1..5;
say @a[0..2];     # OUTPUT: «(1 2 3)␤»
say @a[0..^2];    # OUTPUT: «(1 2)␤»
say @a[0..*];     # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..^*];    # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..Inf-1]; # OUTPUT: «(1 2 3 4 5)␤»

Array Constructor Context

Inside an Array Literal, the list of initialization values is not in capture context and is just a normal list. It is, however, eagerly evaluated just as in assignment.

say so [ 1, 2, :c(3) ] eqv Array.new((1, 2, :c(3))); # OUTPUT: «True␤»
[while $++ < 2 { 42.say; 43 }].map: *.say;           # OUTPUT: «42␤42␤43␤43␤»
(while $++ < 2 { 42.say; 43 }).map: *.say;           # OUTPUT: «42␤43␤42␤43␤»

Which brings us to Arrays...

Arrays

Arrays differ from lists in three major ways: Their elements may be typed, they automatically itemize their elements, and they are mutable. Otherwise they are Lists and are accepted wherever lists are.

say Array ~~ List     # OUTPUT: «True␤»

A fourth, more subtle, way they differ is that when working with Arrays, it can sometimes be harder to maintain laziness or work with infinite sequences.

Typing

Arrays may be typed such that their slots perform a typecheck whenever they are assigned to. An Array that only allows Int values to be assigned is of type Array[Int] and one can create one with Array[Int].new. If you intend to use an @-sigiled variable only for this purpose, you may change its type by specifying the type of the elements when declaring it:

my Int @a = 1, 2, 3;              # An Array that contains only Ints 
 my @b := Array[Int].new(1, 2, 3); # Same thing, but the variable is not typed 
 my @b := Array[Int](1, 2, 3);     # Rakudo shortcut for the same code 
 say @b eqv @a;                    # says True. 
 my @c = 1, 2, 3;                  # An Array that can contain anything 
 say @b eqv @c;                    # says False because types do not match 
 say @c eqv (1, 2, 3);             # says False because one is a List 
 say @b eq @c;                     # says True, because eq only checks values 
 say @b eq (1, 2, 3);              # says True, because eq only checks values 
 
 @a[0] = 42;                       # fine 
 @a[0] = "foo";                    # error: Type check failed in assignment 

In the above example we bound a typed Array object to a @-sigil variable for which no type had been specified. The other way around does not work – you may not bind an Array that has the wrong type to a typed @-sigiled variable:

my @a := Array[Int].new(1, 2, 3);     # fine 
 @a := Array[Str].new("a", "b");       # fine, can be re-bound 
 my Int @b := Array[Int].new(1, 2, 3); # fine 
 @b := Array.new(1, 2, 3);             # error: Type check failed in binding 

When working with typed arrays, it is important to remember that they are nominally typed. This means the declared type of an array is what matters. Given the following sub declaration:

sub mean(Int @a) {
    @a.sum / @a.elems
}

Calls that pass an Array[Int] will be successful:

my Int @b = 1, 3, 5; 
 say mean(@b);                       # @b is Array[Int] 
 say mean(Array[Int].new(1, 3, 5));  # Anonymous Array[Int] 
 say mean(my Int @ = 1, 3, 5);       # Another anonymous Array[Int] 

However, the following calls will all fail, due to passing an untyped array, even if the array just happens to contain Int values at the point it is passed:

my @c = 1, 3, 5; 
 say mean(@c);                       # Fails, passing untyped Array 
 say mean([1, 3, 5]);                # Same 
 say mean(Array.new(1, 3, 5));       # Same again 

Note that in any given compiler, there may be fancy, under-the-hood, ways to bypass the type check on arrays, so when handling untrusted input, it can be good practice to perform additional type checks, where it matters:

for @a -> Int $i { $_++.say }; 

However, as long as you stick to normal assignment operations inside a trusted area of code, this will not be a problem, and typecheck errors will happen promptly during assignment to the array, if they cannot be caught at compile time. None of the core functions provided in Perl 6 for operating on lists should ever produce a wonky typed Array.

Nonexistent elements (when indexed), or elements to which Nil has been assigned, will assume a default value. This default may be adjusted on a variable-by-variable basis with the is default trait. Note that an untyped @-sigiled variable has an element type of Mu, however its default value is an undefined Any:

my @a;
@a.of.perl.say;                 # OUTPUT: «Mu␤»
@a.default.perl.say;            # OUTPUT: «Any␤»
@a[0].say;                      # OUTPUT: «(Any)␤»
my Numeric @n is default(Real);
@n.of.perl.say;                 # OUTPUT: «Numeric␤»
@n.default.perl.say;            # OUTPUT: «Real␤»
@n[0].say;                      # OUTPUT: «(Real)␤»

Fixed Size Arrays

To limit the dimensions of an Array provide the dimensions separated by , or ; in brackets after the name of the array container. The values of such an Arrays will default to Any. The shape can be accessed at runtime via the shape method.

my @a[2,2];
say @a.perl;
# OUTPUT: «Array.new(:shape(2, 2), [Any, Any], [Any, Any])␤»
say @a.shape;
# OUTPUT: «(2 2)␤»

Assignment to a fixed size Array will promote a List of Lists to an Array of Arrays.

my @a[2;2] = (1,2; 3,4);
@a[1;1] = 42;
say @a.perl;
# OUTPUT: «Array.new(:shape(2, 2), [1, 2], [3, 42])␤»

Itemization

For most uses, Arrays consist of a number of slots each containing a Scalar of the correct type. Each such Scalar, in turn, contains a value of that type. Perl 6 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 Perl 6 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. On the other side, Array.perl does not put $ to explicitly show scalars, unlike List.perl:

((1, 2), $(3, 4)).perl.say; # says "((1, 2), $(3, 4))"
[(1, 2), $(3, 4)].perl.say; # says "[(1, 2), (3, 4)]"
                            # ...but actually means: "[$(1, 2), $(3, 4)]"

It was decided all those extra dollar signs and parentheses were more of an eye sore than a benefit to the user. Basically, when you see a square bracket, remember the invisible dollar signs.

Second, remember that these invisible dollar signs also protect against flattening, so you cannot really flatten the elements inside of an Array with a normal call to flat or .flat.

((1, 2), $(3, 4)).flat.perl.say; # OUTPUT: «(1, 2, $(3, 4)).Seq␤»
[(1, 2), $(3, 4)].flat.perl.say; # OUTPUT: «($(1, 2), $(3, 4)).Seq␤»

Since the square brackets do not themselves protect against flattening, you can still spill the elements out of an Array into a surrounding list using flat.

(0, [(1, 2), $(3, 4)], 5).flat.perl.say; # OUTPUT: «(0, $(1, 2), $(3, 4), 5).Seq␤»

...the elements themselves, however, stay in one piece.

This can irk users of data you provide if you have deeply nested Arrays where they want flat data. Currently they have to deeply map the structure by hand to undo the nesting:

say gather [0, [(1, 2), [3, 4]], $(5, 6)].deepmap: *.take; # OUTPUT: «(1 2 3 4 5 6)␤»

...future versions of Perl 6 might find a way to make this easier. However, not returning Arrays or itemized lists from functions, when non-itemized lists are sufficient, is something that one should consider as a courtesy to their users:

The fact that all elements of an array are itemized (in Scalar containers) is more a gentleman's agreement than a universally enforced rule, and it is less well enforced that typechecks in typed arrays. See the section below on binding to Array slots.

Literal Arrays

Literal Arrays are constructed with a List inside square brackets. The List is eagerly iterated (at compile time if possible) and values in the list are each type-checked and itemized. The square brackets themselves will spill elements into surrounding lists when flattened, but the elements themselves will not spill due to the itemization.

Mutability

Unlike lists, Arrays are mutable. Elements may deleted, added, or changed.

my @a = "a", "b", "c";
@a.say;                  # OUTPUT: «[a b c]␤»
@a.pop.say;              # OUTPUT: «c␤»
@a.say;                  # OUTPUT: «[a b]␤»
@a.push("d");
@a.say;                  # OUTPUT: «[a b d]␤»
@a[1, 3] = "c", "c";
@a.say;                  # OUTPUT: «[a c d c]␤»

Assigning

Assignment of a list to an Array is eager. The list will be entirely evaluated, and should not be infinite or the program may hang. Assignment to a slice of an Array is, likewise, eager, but only up to the requested number of elements, which may be finite:

my @a;
@a[0, 1, 2] = (loop { 42 });
@a.say;                     # OUTPUT: «[42 42 42]␤»

During assignment, each value will be typechecked to ensure it is a permitted type for the Array. Any Scalar will be stripped from each value and a new Scalar will be wrapped around it.

Binding

Individual Array slots may be bound the same way $-sigiled variables are:

my $b = "foo";
my @a = 1, 2, 3;
@a[2] := $b;
@a.say;          # OUTPUT: «[1 2 "foo"]␤»
$b = "bar";
@a.say;          # OUTPUT: «[1 2 "bar"]␤»

...but binding Array slots directly to values is strongly discouraged. If you do, expect surprises with built-in functions. The only time this would be done is if a mutable container that knows the difference between values and Scalar-wrapped values is needed, or for very large Arrays where a native-typed array cannot be used. Such a creature should never be passed back to unsuspecting users.

31 Doing math with Perl 6

Different mathematical paradigms and how they are implemented in this language

Sets.

Perl 6 includes the Set data type, as well as support for most set operations. Union and intersection are not only native operations, they use their natural symbols, ∩ and ∪. For instance, this code would check the fundamental laws of the arithmetic of sets for a limited number of sets:

my @arbitrary-numbers = ^100; 
 my \U = @arbitrary-numbers.Set; 
 
 my @sets; 
 
 @sets.push: Set.new( @arbitrary-numbers.pick( @arbitrary-numbers.elems.rand)) for @arbitrary-numbers; 
 
 my (@union, @intersection); 
 
 for @sets -> $set { 
     @union.push: $set ∩ $set === $set; 
     @intersection.push: $set ∪ $set === $set; 
 } 
 
 say "Idempotent union is ", so @union.all; 
 # OUTPUT: «Idempotent union is True» 
 say "Idempotent intersection is ", so @intersection.all; 
 # OUTPUT: «Idempotent intersection is True» 
 my (@universe, @empty-set, @id-universe, @id-empty); 
 
 for @sets -> \A { 
     @universe.push: A ∪ U === U; 
     @id-universe.push: A ∩ U === A; 
     @empty-set.push: A ∩ ∅ === ∅; 
     @id-empty.push: A ∪ ∅ === A; 
 } 
 
 say "Universe dominates ", so @universe.all;    # OUTPUT: «Universe dominates True» 
 say "Empty set dominates ", so @empty-set.all;  # OUTPUT: «Empty set dominates True» 
 
 say "Identity with U ", so @id-universe.all;    # OUTPUT: «Identity with U True» 
 say "Identity with ∅ ", so @id-empty.all;       # OUTPUT: «Identity with ∅ True» 

In this code, which uses the empty set which is already defined by Perl 6, not only we check if the equalities in the algebra of sets hold, we also use, via sigilless variables and the Unicode form of the set operators, expressions that are as close as possible to the original form; A ∪ U === U, for example, except for the use of the value identity operator <===> is very close to the actual mathematical expression in the Wikipedia entry.

We can even test de Morgan's law, as in the code below:

my @alphabet = 'a'..'z'; 
 my \U = @alphabet.Set; 
 sub postfix:<⁻>(Set $a) { U ⊖ $a } 
 my @sets; 
 @sets.push: Set.new( @alphabet.pick( @alphabet.elems.rand)) for @alphabet; 
 my ($de-Morgan1,$de-Morgan2) = (True,True); 
 for @sets X @sets -> (\A, \B){ 
     $de-Morgan1 &&= (A ∪ B)⁻  === A⁻ ∩ B⁻; 
     $de-Morgan2 &&= (A ∩ B)⁻  === A⁻ ∪ B⁻; 
 } 
 say "1st De Morgan is ", $de-Morgan1; 
 say "2nd De Morgan is ", $de-Morgan2; 

We declare as the complement operation, which computes the symmetrical difference ⊖ between the Universal set U and our set. Once that is declared, it is relatively easy to express operations such as the complementary of the union of A and B (A ∪ B)⁻, with a notation that is very close to the original mathematical notation.

Arithmetic.

Perl 6 can do arithmetic using different data types. Num, Rat and Complex can all operate as a field under the operations addition, subtraction, multiplication and division. The equivalent mathematical fields are:

Perl 6 class Field
C<Rat>
C<Num>
C<Complex>

The Ints, although technically corresponding to Z, is not really a mathematical field since they are not closed under the four arithmetical operations, and integers do not satisfy the identity axiom. However, if the integer division div is used, their operations will always yield other integers; if / is used, however, in general the result will be a Rat.

Besides, Int can do infinite-precision arithmetic (or at least infinite as memory allows; Numeric overflow can still occur), without falling back to Num if the number is too big:

my @powers = 2, 2 ** * ... Inf; say @powers[4].chars; # OUTPUT: «19729␤»

Also strictly speaking, the Rational class that behaves like a mathematical field is FatRat. For efficiency reasons, operating with Rats will fall back ton Num when the numbers are big enough or when there is a big difference between numerator and denominator. FatRat can work with arbitrary precision, the same as the default Int class.

Some modules in the ecosystem can work with additional data types mathematically:

Numbers are duck-typed automatically to the numeric class they actually represent:

.^name.say for (4, ⅗, 1e-9, 3+.1i); # OUTPUT: «Int␤Rat␤Num␤Complex␤»

Which makes also arithmetic operations the most adequate for the particular type

say .33-.22-.11 == 0; # OUTPUT: «True␤»

In this case, all numbers are interpreted as Rats, which makes the operation exact. In general, most languages would interpret them as floating point numbers,

say .33.Num -.22.Num - .11.Num; # OUTPUT: «1.3877787807814457e-17␤»

For cases such as this, Perl 6 also includes an approximately equal operator,

say .33.Num -.22.Num - .11.Num ≅ 0; # OUTPUT: «True␤»

Sequences

A sequence is an enumerated collection of objects in which repetitions are allowed>, and also a first-class data type in Perl 6 called Seq. Seq is able to represent infinite sequences, like the natural numbers:

my \𝕟 = 1,2 … ∞;
say 𝕟[3];# OUTPUT: «4␤»

Infinite sequences use ∞, Inf or * (Whatever) as terminator. is the list generator, which in fact can understand arithmetic and geometric progression sequences as long as you insert the first numbers:

say 1,5,9 … * > 100;
# OUTPUT: «(1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101)␤»
say 1,3,9 … * > 337; # OUTPUT: «(1 3 9 27 81 243 729)␤»

The first sequence will be terminated when the generated number is bigger than 100; the second sequence, which is a geometric progression, when it is bigger than 337.

The fact that an arbitrary generator can be used makes easy to generate sequences such as Fibonacci's:

say 1,1, * + * … * > 50;#  OUTPUT: «(1 1 2 3 5 8 13 21 34 55)␤»

We can, in fact, compute the approximation to the golden ratio this way:

my @phis = (2.FatRat, 1 + 1 / * ... *);
my @otherphi = (1 - @phis[200], 1 + 1 / * ... *);
say @otherphi[^10, |(20, 30 ... 100)];# OUTPUT:
# «((-0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.618033…»

The Math::Sequences module includes many mathematical sequences, already defined for you. It defines many sequences from the encyclopedia, some of them with their original name, such as ℤ or ℝ.

Some set operators also operate on sequences, and they can be used to find out if an object is part of it:

say 876 ∈ (7,14 … * > 1000) ; # OUTPUT: «False␤»

In this particular case, we can find out if 876 is a multiple of 7 straight away, but the same principle holds for other sequences using complicated generators. And we can use set inclusion operators too:

say (55,89).Set ⊂ (1,1, * + * … * > 200); # OUTPUT: «True␤»

although it does not take into account if it is effectively a subsequence, just the presence of the two elements here; Sets have no order, and even if you don't explicitly cast the subsequence into a Set or explicitly cast it into a Seq it will be coerced into such for the application of the inclusion operator.

Mathematical constants

Perl 6 includes already a set of mathematical constants as part of the core.

say π; # OUTPUT: «3.141592653589793»
say τ; # Equivalent to 2π; OUTPUT: «6.283185307179586»
say 𝑒; # OUTPUT: «2.718281828459045␤»

which are available also by their Latin name, e, pi and tau, with the same value (although 𝑒 is not available outside the MoarVM).

The Math::Constants module includes an additional series of physical and mathematical constants such as the previously mentioned golden ratio φ or the Planck's constant ℎ.

Since Perl 6 allows for definition of variables that use Unicode graphemes, and also variable and constant names without any kind of sigil, it is considered a good practice to use the actual mathematical name of concepts to denominate them wherever possible.

32 Module Packages

Creating module packages for code reuse

N.B. "Module" is an overloaded term in Perl 6; this document focuses on use of the module declarator.

What are modules?

Modules, like classes and grammars, are a kind of package. Module objects are instances of the ModuleHOW metaclass; this provides certain capabilities useful for creating namespaces, versioning, delegation and data encapsulation (see also class and role).

To create a module, use the module declarator:

module M {}
say M.HOW;   # OUTPUT: «Perl6::Metamodel::ModuleHOW.new␤»

Here we define a new module named M; introspection with HOW confirms that the metaclass underlying M is Perl6::Metamodel::ModuleHOW.

When to use modules

Modules are primarily useful for encapsulating code and data that do not belong inside a class or role definition. Module contents (classes, subroutines, variables, etc.) can be exported from a module with the is export trait; these are available in the caller's namespace once the module has been imported with import or use. A module can also selectively expose symbols within its namespace for qualified reference via our.

Working with modules

To illustrate module scoping and export rules, let's begin by defining a simple module M:

module M {
  sub greeting ($name = 'Camelia') { "Greetings, $name!" }
  our sub loud-greeting (--> Str)  { greeting().uc       }
  sub friendly-greeting is export  { greeting('friend')  }
}

Recall that subroutines are lexically scoped unless otherwise specified (declarator sub is equivalent to my sub), so greeting in the above example is lexically scoped to the module and inaccessible outside of it. We've also defined loud-greeting with the our declarator, which means that in addition to being lexically scoped it is aliased in the module's symbol table. Finally, friendly-greeting is marked for export; it will be registered in the caller's symbol table when the module is imported:

import M;               # import the module 
 say M::loud-greeting;   # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;  # OUTPUT: «Greetings, friend!␤» 

Modules on disk

While .pm and .pm6 files (hereafter: .pm6) are sometimes referred to as "modules", they are really just normal files that are loaded and compiled when you write need, use or require.

For a .pm6 file to provide a module in the sense that we've been using, it needs to declare one with module as documented above. For example, by placing module M inside Foo.pm6, we can load and use the module as follows:

use Foo;                # find Foo.pm6, run need followed by import 
 say M::loud-greeting;   # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;  # OUTPUT: «Greetings, friend!␤» 

Note the decoupling between file and module names—a .pm6 file can declare zero or more modules with arbitrary identifiers.

File and module naming

Often we want a .pm6 file to provide a single module and nothing more. Here a common convention is for the file basename to match the module name. Returning to Foo.pm6, it is apparent that it only provides a single module, M; in this case, we might want to rename M to Foo. The amended file would then read:

module Foo { 
   sub greeting ($name = 'Camelia') { "Greetings, $name!" } 
   our sub loud-greeting (--> Str)  { greeting().uc       } 
   sub friendly-greeting is export  { greeting('friend')  } 
 } 

which can be used more consistently by the caller (note the relationship between the use Foo and Foo::):

use Foo; 
 say Foo::loud-greeting;  # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings, friend!␤» 

If Foo.pm6 is placed deeper within the source tree, e.g. at lib/Utils/Foo.pm6, we can elect to name the module Utils::Foo to maintain consistency.

The unit keyword

Files that only provide a single module can be written more concisely with the unit keyword; unit module specifies that the rest of the compilation unit is part of the declared module. Here's Foo.pm6 rewritten with unit:

unit module Foo; 
 
 sub greeting ($name = 'Camelia') { "Greetings, $name!" } 
 our sub loud-greeting (--> Str)  { greeting().uc       } 
 sub friendly-greeting is export  { greeting('friend')  } 

Everything following the unit declaration is part of the Foo module specification.

(Note that unit can also be used with class, grammar and role.)

What happens if I omit module?

To better understand what the module declarator is doing in Foo.pm6, let's contrast it with a variant file, Bar.pm6, that omits the declaration. The subroutine definitions below are almost identical (the only difference is in the body of greeting, modified for clarity):

sub greeting ($name = 'Camelia') { "Greetings from Bar, $name!" } 
 our sub loud-greeting (--> Str)  { greeting().uc                } 
 sub friendly-greeting is export  { greeting('friend')           } 

As a reminder, here's how we used Foo.pm6 before,

use Foo; 
 say Foo::loud-greeting;  # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings, friend!␤» 

and here's how we use Bar.pm6,

use Bar; 
 say loud-greeting;       # OUTPUT: «GREETINGS FROM BAR, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings from Bar, friend!␤» 

Note the use of loud-greeting rather than Bar::loud-greeting as Bar is not a known symbol (we didn't create a module of that name in Bar.pm6). But why is loud-greeting callable even though we didn't mark it for export? The answer is simply that Bar.pm6 doesn't create a new package namespace—$?PACKAGE is still set to GLOBAL—so when we declare loud-greeting as our, it is registered in the GLOBAL symbol table.

Lexical aliasing and safety

Thankfully, Perl 6 protects us from accidentally clobbering call site definitions (e.g. builtins). Consider the following addition to Bar.pm6:

our sub say ($ignored) { print "oh dear\n" }

This creates a lexical alias, hiding the say builtin inside Bar.pm6 but leaving the caller's say unchanged. Consequently, the following call to say still works as expected:

use Bar; 
 say 'Carry on, carry on...';  # OUTPUT: «Carry on, carry on...␤» 

33 Core modules

Core modules that may be useful to module authors

The Rakudo implementation has a few modules included you may want to use. The following is a list of them, along with links to their source code.

CompUnit::* modules and Roles

These modules are mostly used by distribution build tools, and are not intended to be used (at least until version 6.c) by the final user.

NativeCall modules

Other modules

34 Module Development Utilities

What can help you write/test/improve your module(s)

Here is a list of modules that you can find in the Perl 6 ecosystem which aim to make the experience of developing Perl 6 modules more fun.

Module builder and Authoring tools

Some modules and tools to help you with generating files that are part of a module distribution.

Tests

Some tests of module quality.

NativeCall

Here some modules to help you work with NativeCall.

Sample modules

Modules that exist only as minimalist examples, tests for installers, or skeletons.

35 Modules

How to create, use and distribute Perl 6 modules

Creating and Using Modules

A module is usually a source file or set of source files

Technically a module is a set of compunits which are usually files but could come from anywhere as long as there is a compunit repository that can provide it. See S11 .
that expose Perl 6 constructs. These are typically packages (classes, roles, grammars), subroutines, and sometimes variables. In Perl 6 module can also refer to a type of package declared with the module keyword (see Module Packages and the examples below) but here we mostly mean "module" as a set of source files in a namespace.

Looking for and installing modules.

zef is the application using for installing modules in Perl 6. Modules are listed in the Perl 6 ecosystem and can be searched there or from the command line using zef search

    zef search WWW 

will return a list of modules that includes WWW in their name, for instance. Then,

    zef install WWW 

will install the module with that particular name, if it is not already installed.

Basic Structure

Module distributions (in the set of related source files sense) in Perl 6 have the same structure as any distribution in the Perl family of languages: there is a main project directory containing a README and a LICENSE file, a lib directory for the source files, which may be individually referred to as modules and/or may themselves define modules with the module keyword

As synopsis S11 says: Confusing? Yes it is.
, a t directory for tests, and possibly a bin directory for executable programs and scripts.

Source files generally use the .pm6 extension, and scripts or executables use the .p6. Test files use the .t extension. Files which contain documentation use the .pod6 extension.

Loading and Basic Importing

Loading a module makes the packages in the same namespace declared within available in the file scope of the loader. Importing from a module makes the symbols exported available in the lexical scope of the importing statement.

need

need loads a compunit at compile time.

need MyModule; 

Any packages in the namespace defined within will also be available.

# MyModule.pm6 
 unit module MyModule; 
 
 class MyModule::Class {} 

MyModule::Class will be defined when MyModule is loaded.

class Class { ... } won't get exported automatically on loading...not sure if bug or..

use

use loads and then imports from a compunit at compile time. It will look for files that end in .pm6 (.pm is also supported). See here for where the runtime will look for modules.

use MyModule; 

It is equivalent to:

need  MyModule; 
 import MyModule; 

See also Selective Importing to restrict what you import.

require

require loads a compunit and imports definite symbols at runtime.

say "loading MyModule";
require MyModule;

The compunit name can be in a runtime variable if you put it inside an indirect lookup.

my $name = 'MyModule';
require ::($name);

The symbols provided by the loaded module will not be imported into the current scope. You may use dynamic lookup or dynamic subsets to use them by providing the fully qualified name of a symbol, for instance:

require ::("Test");
my &mmk = ::("Test::EXPORT::DEFAULT::&ok");
mmk('oi‽'); # OUTPUT: «ok 1 - ␤»

The FQN of ok is Test::EXPORT::DEFAULT::&ok. We are aliasing it to mmk so that we can use that symbol provided by Test in the current scope.

To import symbols you must define them at compile time. NOTE: require is lexically scoped:

sub do-something {
   require MyModule <&something>;
   say ::('MyModule'); # MyModule symbol exists here
   something() # &something will be defined here
}
say ::('MyModule'); # This will NOT contain the MyModule symbol
do-something();
# &something will not be defined here

If MyModule doesn't export &something then require will fail.

A require with compile-time symbol will install a placeholder package that will be updated to the loaded module, class, or package. Note that the placeholder will be kept, even if require failed to load the module. This means that checking if a module loaded like this is wrong:

# *** WRONG: ***
try require Foo;
if ::('Foo') ~~ Failure { say "Failed to load Foo!"; }
# *** WRONG: ***

As the compile-time installed package causes ::('Foo') to never be a Failure. The correct way is:

# Use return value to test whether loading succeeded:
(try require Foo) === Nil and say "Failed to load Foo!";

# Or use a runtime symbol lookup with require, to avoid compile-time
# package installation:
try require ::('Foo');
if ::('Foo') ~~ Failure {
    say "Failed to load Foo!";
}

Lexical module loading

Perl 6 takes great care to avoid global state, i.e. whatever you do in your module, it should not affect other code. That's why e.g. subroutine definitions are lexically (my) scoped by default. If you want others to see them, you need to explicitly make them our scoped or export them.

Classes are exported by default on the assumption that loading a module will not be of much use when you cannot access the classes it contains. This works as advertised with a small but important caveat: those classes are not only visible in the computation unit that loads the module, but globally. This means that as soon as some code loads a module, those classes are immediately visible everywhere.

For example, given a module Foo:

unit class Foo; 
 use Bar; 

And your own program:

use Foo; 
 my $foo = Foo.new; # works as expected 
 my $bar = Bar.new; # huh!? Where is Bar coming from? 

This doesn't sound so bad (it at least saves you some typing), except for that it makes another feature of Perl 6 impossible to have: the ability to load multiple versions of a module at the same time in different parts of your program:

{ 
     use Baz:ver(v1); 
     my $old-baz = Baz.new; 
 } 
 { 
     use Baz:ver(v2); 
     my $shiny-new-baz = Baz.new; 
 } 

This will explode as on loading Baz:ver(v2), Rakudo will complain about "Baz" already being defined.

To fix this, we no longer register loaded classes globally but only in the scope which loaded them in the first place. Coming back to our first example, we would need to explicitly load Bar in the main program:

use Foo; 
 use Bar; 
 my $foo = Foo.new; # still works of course 
 my $bar = Bar.new; # now it's clear where Bar is coming from 

So if you suddenly get an "Undeclared name: Bar" error message after upgrading to a newer Perl 6 compiler, you will most probably just need to add a: "use Bar;" to your code.

Exporting and Selective Importing

is export

Packages, subroutines, variables, constants and enums are exported by marking them with the is export trait (also note the tags available for indicating authors and versions).

unit module MyModule:ver<1.0.3>:auth<John Hancock (jhancock@example.com)>; 
 our $var is export = 3; 
 sub foo is export { ... }; 
 constant FOO is export = "foobar"; 
 enum FooBar is export <one two three>; 
 
 # Packages like classes can be exported too 
 class MyClass is export {}; 
 
 # If a subpackage is in the namespace of the current package 
 # it doesn't need to be explicitly exported 
 class MyModule::MyClass {}; 

As with all traits, if applied to a routine, "is export" should appear after any argument list.

sub foo(Str $string) is export { ... } 

You can pass named parameters to is export to group symbols for exporting so that the importer can pick and choose. There are three predefined tags: ALL, DEFAULT and MANDATORY.

# lib/MyModule.pm6 
 unit module MyModule; 
 sub bag        is export             { ... } 
 sub pants      is export(:MANDATORY) { ... } # objects with tag ':MANDATORY' are always exported 
 sub sunglasses is export(:day)       { ... } 
 sub torch      is export(:night)     { ... } 
 sub underpants is export(:ALL)       { ... } 
# main.p6 
 use lib 'lib'; 
 use MyModule;          # bag, pants 
 use MyModule :DEFAULT; # the same 
 use MyModule :day;     # pants, sunglasses 
 use MyModule :night;   # pants, torch 
 use MyModule :ALL;     # bag, pants, sunglasses, torch, underpants 

Note there currently is no way for the user to import a single object if the module author hasn't made provision for that, and it is not an easy task at the moment (see RT #127305). One way the author can provide such access is to give each export trait its own unique tag. (And the tag can be the object name!) Then the user can either (1) import all objects:

use Foo :ALL; 

or (2) import one or more objects selectively:

use Foo :bar, :s5; 

Notes:

1. The :MANDATORY tag on an exported sub ensures it will be exported no matter whether the using program adds any tag or not.

2. All exported subs without an explicit tag are implicitly :DEFAULT.

3. The space after the module name and before the tag is mandatory.

4. Multiple import tags may be used (separated by commas). For example:

# main.p6 
 use lib 'lib'; 
 use MyModule :day, :night; # pants, sunglasses, torch 

5. Multiple tags may be used in the export trait, but they must all be separated by either commas, or whitespace, but not both.

sub foo() is export(:foo :s2 :net) {} 
 sub bar() is export(:bar, :s3, :some) {} 

UNIT::EXPORT::*

Beneath the surface, is export is adding the symbols to a UNIT scoped package in the EXPORT namespace. For example, is export(:FOO) will add the target to the UNIT::EXPORT::FOO package. This is what Perl 6 is really using to decide what to import.

unit module MyModule; 
 
 sub foo is export { ... } 
 sub bar is export(:other) { ... } 

Is the same as:

unit module MyModule; 
 
 my package EXPORT::DEFAULT { 
     our sub foo { ... } 
 } 
 
 my package EXPORT::other { 
     our sub bar { ... } 
 } 

For most purposes is export is sufficient but the EXPORT packages are useful when you want to produce the exported symbols dynamically. For example:

# lib/MyModule.pm6 
 unit module MyModule; 
 
 my package EXPORT::DEFAULT { 
    for <zero one two three four>.kv -> $number, $name { 
       for <sqrt log> -> $func { 
          OUR::{'&' ~ $func ~ '-of-' ~ $name } := sub { $number."$func"() }; 
       } 
    } 
 } 
 
# main.p6 
 use MyModule; 
 say sqrt-of-four; # OUTPUT: «2␤» 
 say log-of-zero;  # OUTPUT: «-Inf␤» 

EXPORT

You can export arbitrary symbols with an EXPORT sub. EXPORT must return a Map, where the keys are the symbol names and the values are the desired values. The names should include the sigil (if any) for the associated type.

# lib/MyModule.pm6 
 
 class MyModule::Class { } 
 
 sub EXPORT { 
     %( 
       '$var'      => 'one', 
       '@array'    => <one two three>, 
       '%hash'     => %( one => 'two', three => 'four' ), 
       '&doit'     => sub { say 'Greetings from exported sub' }, 
       'ShortName' => MyModule::Class 
     ) 
 } 
# main.p6 
 use lib 'lib'; 
 use MyModule; 
 say $var;          # OUTPUT: «one␤» 
 say @array;        # OUTPUT: «(one two three)␤» 
 say %hash;         # OUTPUT: «{one => two, three => four}␤» 
 doit();            # OUTPUT: «Greetings from exported sub␤» 
 say ShortName.new; # OUTPUT: «MyModule::Class.new␤» 

Note, EXPORT can't be declared inside a package because it is part of the compunit rather than the package.

Whereas UNIT::EXPORT packages deal with the named parameters passed to use, the EXPORT sub handles positional parameters. If you pass positional parameters to use they will be passed to EXPORT. If a positional is passed the module no longer exports default symbols. You may still import them explicitly by passing :DEFAULT to use along with your positional parameters.

# lib/MyModule 
 
 class MyModule::Class {} 
 
 sub EXPORT($short_name?) { 
     %( 
       do $short_name => MyModule::Class if $short_name 
     ) 
 } 
 
 sub always is export(:MANDATORY) { say "works" } 
 
 #import with :ALL or :DEFAULT to get 
 sub shy is export { say "you found me!" } 
# main.p6 
 use lib 'lib'; 
 use MyModule 'foo'; 
 say foo.new(); # OUTPUT: «MyModule::Class.new␤» 
 
 always();      # OK   - is imported 
 shy();         # FAIL - won't be imported 

You can combine EXPORT with type captures for interesting effect. This example creates a ? postfix which will only work on Cools.

# lib/MakeQuestionable.pm6 
 sub EXPORT(::Questionable) { 
     my multi postfix:<?>(Questionable $_) { .so }; 
     %( 
       '&postfix:<?>' => &postfix:<?>, 
     ) 
 } 
use MakeQuestionable Cool; 
 say ( 0?, 1?, {}?, %( a => "b" )? ).join(' '); # OUTPUT: «False True False True␤» 

Introspection

To list exported symbols of a module first query the export tags supported by the module.

use URI::Escape;
say URI::Escape::EXPORT::.keys;
# OUTPUT: «(DEFAULT ALL)␤»

Then use the tag you like and pick the symbol by its name.

say URI::Escape::EXPORT::DEFAULT::.keys;
# OUTPUT: «(&uri-escape &uri-unescape &uri_escape &uri_unescape)␤»
my &escape-uri = URI::Escape::EXPORT::DEFAULT::<&uri_escape>;

Be careful not to put sub EXPORT after unit declarator. If you do so, it'll become just a sub inside your package, rather than the special export sub:

    unit module Bar; 
     sub EXPORT { %(Foo => &say) } # WRONG!!! Sub is scoped wrong 
 
     # --------- 
 
     sub EXPORT { %(Foo => &say) } # RIGHT!!! Sub is outside the module 
     unit module Bar; 

Finding Modules

It is up to the module installer to know where compunit expects modules to be placed. There will be a location provided by the distribution and in the current home directory. In any case, letting the module installer deal with your modules is a safe bet.

cd your-module-dir 
 zef --force install . 

A user may have a collection of modules not found in the normal ecosystem, maintained by a module or package manager, but needed regularly. Instead of using the use lib pragma one can use the PERL6LIB environment variable to point to module locations. For example:

export PERL6LIB=/path/to/my-modules,/path/to/more/modules 

Note that the comma (',') is used as the directory separator.

The include path will be searched recursively for any modules when Rakudo is started. Directories that start with a dot are ignored and symlinks are followed.

Distributing Modules

If you've written a Perl 6 module and would like to share it with the community, we'd be delighted to have it listed in the Perl 6 modules directory. :)

Currently there are two different module ecosystems (module distribution networks) available:

The process of sharing your module consists of two steps, preparing the module and uploading the module to one of the ecosystems.

Preparing the Module

For a module to work in any of the ecosystems, it needs to follow a certain structure. Here is how to do that:

Upload your Module to CPAN

Uploading a module to CPAN is the preferred way of distributing Perl 6 modules.

it requires having a PAUSE user account. If you don't have an account already go there and apply for an account. The process takes about 5 minutes and some e-mail back and forth.

Upload your Module to p6c

If you want to use the p6c ecosystem you need to use git for your module's version control. The instructions herein assume that you have a GitHub account so that your module can be shared from its GitHub repository, however another provider such as GitLab should work as long as it works in a similar way.

That's it! Thanks for contributing to the Perl 6 community!

If you'd like to try out installing your module, use the zef module installer tool which is included with Rakudo Star Perl 6:

zef install Vortex::TotalPerspective 

This will download your module to its own working directory (~/.zef), build it there, and install the module into your local Perl 6 installation directory.

To use Vortex::TotalPerspective from your scripts, just write use Vortex::TotalPerspective, and your Perl 6 implementation will know where to look for the module file(s).

Modules and Tools Related to Module Authoring

You can find a list of modules and tools that aim to improve the experience of writing/test modules at Modules Extra

Contact Information

To discuss module development in general, or if your module would fill a need in the ecosystem, naming, etc., you can use the #perl6 on irc.freenode.net IRC channel.

To discuss toolchain specific questions, you can use the #perl6-toolchain on irc.freenode.net IRC channel. A repository to discuss tooling issues is also available at https://github.com/perl6/toolchain-bikeshed.

36 Meta-Object Protocol

Introspection and the Perl 6 object system

Perl 6 is built on a meta object layer. That means that there are objects (the meta objects) that control how various object-oriented constructs (such as classes, roles, methods, attributes or enums) behave.

To get a feeling for the meta object for class, here is the same example twice: once as normal declarations in Perl 6, and once expressed through the meta model:

class A {
    method x() { say 42 }
}

A.x();

corresponds to:

constant A := Metamodel::ClassHOW.new_type( name => 'A' );  # class A {
A.^add_method('x', my method x(A:) { say 42 });             #   method x()
A.^compose;                                                 # }

A.x();

(except that the declarative form runs at compile time, and the latter form does not).

The meta object behind an object can be obtained with $obj.HOW, where HOW stands for Higher Order Workings (or, HOW the *%@$ does this work?).

Here, the calls with .^ are calls to the meta object, so A.^compose is a shortcut for A.HOW.compose(A). The invocant is passed in the parameter list as well, to make it possible to support prototype-style type systems, where there is just one meta object (and not one meta object per type, as standard Perl 6 does it).

As the example above demonstrates, all object oriented features are available to the user, not just to the compiler. In fact the compiler just uses such calls to meta objects.

Metamethods

These are introspective macros that resemble method calls.

Metamethods are generally named with ALLCAPS, and it is considered good style to avoid creating your own methods with ALLCAPS names. This will avoid conflicts with any metamethods that may appear in future versions of the language.

WHAT

The type object of the type. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

For example 42.WHAT returns the Int type object.

WHICH

The object's identity value. This can be used for hashing and identity comparison, and is how the === infix operator is implemented.

WHO

The package supporting the object.

WHERE

The memory address of the object. Note that this is not stable in implementations with moving/compacting garbage collectors. Use WHICH for a stable identity indicator.

HOW

Returns the metaclass object, as in "Higher Order Workings".

say (%).HOW.^name # OUTPUT: «Perl6::Metamodel::ClassHOW+{<anon>}␤»

HOW returns an object of type Perl6::Metamodel::ClassHOW in this case; objects of this type are used to build classes. The same operation on the & sigil will return Perl6::Metamodel::ParametricRoleGroupHOW. You will be calling this object whenever you use the ^ syntax to access meta methods. In fact, the code above is equivalent to say (&).HOW.HOW.name(&) which is much more unwieldy. Metamodel::ClassHOW is part of the Rakudo implementation, so use with caution.

WHY

The attached Pod value.

DEFINITE

The object has a valid concrete representation. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

Returns True for instances and False for type objects.

VAR

Returns the underlying Scalar object, if there is one.

The presence of a Scalar object indicates that the object is "itemized".

.say for (1, 2, 3);           # OUTPUT: «1␤2␤3␤», not itemized
.say for $(1, 2, 3);          # OUTPUT: «(1 2 3)␤», itemized
say (1, 2, 3).VAR ~~ Scalar;  # OUTPUT: «False␤»
say $(1, 2, 3).VAR ~~ Scalar; # OUTPUT: «True␤»

Structure of the meta object system

Note: this documentation largely reflects the meta object system as implemented by the Rakudo Perl 6 compiler, since the design documents are very light on details.

For each type declarator keyword, such as class, role, enum, module, package, grammar or subset, there is a separate meta class in the Metamodel:: namespace. (Rakudo implements them in the Perl6::Metamodel:: namespace, and then maps Perl6::Metamodel to Metamodel).

Many of the these meta classes share common functionality. For example roles, grammars and classes can all contain methods and attributes, as well as being able to do roles. This shared functionality is implemented in roles which are composed into the appropriate meta classes. For example role Metamodel::RoleContainer implements the functionality that a type can hold roles and Metamodel::ClassHOW, which is the meta class behind the class keyword, does this role.

Most meta classes have a compose method that you must call when you're done creating or modifying a meta object. It creates method caches, validates things and so on, and weird behavior ensues if you forget to call it, so don't :-).

Bootstrapping concerns

You might wonder how Metamodel::ClassHOW can be a class, when being a class is defined in terms of Metamodel::ClassHOW, or how the roles responsible for role handling can be roles. The answer is by magic.

Just kidding. Bootstrapping is implementation specific. Rakudo does it by using the object system of the language in which itself is implemented, which happens to be (nearly) a subset of Perl 6: NQP, Not Quite Perl. NQP has a primitive, class-like kind called knowhow, which is used to bootstrap its own classes and roles implementation. knowhow is built on primitives that the virtual machine under NQP provides.

Since the object model is bootstrapped in terms of lower-level types, introspection can sometimes return low-level types instead of the ones you expect, like an NQP-level routine instead of a normal Routine object, or a bootstrap-attribute instead of Attribute.

Composition time and static reasoning

In Perl 6, a type is constructed as it is parsed, so in the beginning, it must be mutable. However if all types were always mutable, all reasoning about them would get invalidated at any modification of a type. For example the list of parent types and thus the result of type checking can change during that time.

So to get the best of both worlds, there is a time when a type transitions from mutable to immutable. This is called composition, and for syntactically declared types, it happens when the type declaration is fully parsed (so usually when the closing curly brace is parsed).

If you create types through the meta-object system directly, you must call .^compose on them before they become fully functional.

Most meta classes also use composition time to calculate some properties like the method resolution order, publish a method cache, and other house-keeping tasks. Meddling with types after they have been composed is sometimes possible, but usually a recipe for disaster. Don't do it.

Power and Responsibility

The meta object protocol offers much power that regular Perl 6 code intentionally limits, such as calling private methods on classes that don't trust you, peeking into private attributes, and other things that usually simply aren't done.

Regular Perl 6 code has many safety checks in place; not so the meta model. It is close to the underlying virtual machine, and violating the contracts with the VM can lead to all sorts of strange behaviors that, in normal code, would obviously be bugs.

So be extra careful and thoughtful when writing meta types.

Power, Convenience and Pitfalls

The meta object protocol is designed to be powerful enough to implement the Perl 6 object system. This power occasionally comes at the cost of convenience.

For example, when you write my $x = 42 and then proceed to call methods on $x, most of these methods end up acting on the integer 42, not on the scalar container in which it is stored. This is a piece of convenience found in ordinary Perl 6. Many parts of the meta object protocol cannot afford to offer the convenience of automatically ignoring scalar containers, because they are used to implement those scalar containers as well. So if you write my $t = MyType; ... ; $t.^compose you are composing the Scalar that the $-sigiled variable implies, not MyType.

The consequence is that you need to have a rather detailed understanding of the subtleties of Perl 6 in order to avoid pitfalls when working with the MOP, and can't expect the same "do what I mean" convenience that ordinary Perl 6 code offers.

37 Native Calling Interface

Call into dynamic libraries that follow the C calling convention

Getting Started

The simplest imaginable use of NativeCall would look something like this:

use NativeCall;
sub some_argless_function() is native('something') { * }
some_argless_function();

The first line imports various traits and types. The next line looks like a relatively ordinary Perl 6 sub declaration—with a twist. We use the "native" trait in order to specify that the sub is actually defined in a native library. The platform-specific extension (e.g., .so or .dll), as well as any customary prefixes (e.g., 'lib') will be added for you.

The first time you call "some_argless_function", the "libsomething" will be loaded and the "some_argless_function" will be located in it. A call will then be made. Subsequent calls will be faster, since the symbol handle is retained.

Of course, most functions take arguments or return values—but everything else that you can do is just adding to this simple pattern of declaring a Perl 6 sub, naming it after the symbol you want to call and marking it with the "native" trait.

You will also need to declare and use native types. Please check the native types page for more information.

Changing names

Sometimes you want the name of your Perl subroutine to be different from the name used in the library you're loading. Maybe the name is long or has different casing or is otherwise cumbersome within the context of the module you are trying to create.

NativeCall provides a symbol trait for you to specify the name of the native routine in your library that may be different from your Perl subroutine name.

unit module Foo; 
 use NativeCall; 
 our sub init() is native('foo') is symbol('FOO_INIT') { * } 

Inside of libfoo there is a routine called FOO_INIT but, since we're creating a module called Foo and we'd rather call the routine as Foo::init, we use the symbol trait to specify the name of the symbol in libfoo and call the subroutine whatever we want ("init" in this case).

Passing and Returning Values

Normal Perl 6 signatures and the returns trait are used in order to convey the type of arguments a native function expects and what it returns. Here is an example.

use NativeCall;
sub add(int32, int32) returns int32 is native("calculator") { * }

Here, we have declared that the function takes two 32-bit integers and returns a 32-bit integer. You can find the other types that you may pass in the native types page. Note that the lack of a returns trait is used to indicate void return type. Do not use the void type anywhere except in the Pointer parameterization.

For strings, there is an additional encoded trait to give some extra hints on how to do the marshaling.

use NativeCall;
sub message_box(Str is encoded('utf8')) is native('gui') { * }

To specify how to marshal string return types, just apply this trait to the routine itself.

use NativeCall;
sub input_box() returns Str is encoded('utf8') is native('gui') { * }

Note that a NULL string pointer can be passed by passing the Str type object; a NULL return will also be represented by the type object.

If the C function requires the lifetime of a string to exceed the function call, the argument must be manually encoded and passed as CArray[uint8]:

use NativeCall;
# C prototype is void set_foo(const char *)
sub set_foo(CArray[uint8]) is native('foo') { * }
# C prototype is void use_foo(void)
sub use_foo() is native('foo') { * } # will use pointer stored by set_foo()

my $string = "FOO";
# The lifetime of this variable must be equal to the required lifetime of
# the data passed to the C function.
my $array = CArray[uint8].new($string.encode.list);

set_foo($array);
# ...
use_foo();
# It's fine if $array goes out of scope starting from here.

Specifying the native representation

When working with native functions, sometimes you need to specify what kind of native data structure is going to be used. is repr is the term employed for that.

use NativeCall; 
 
 class timespec is repr('CStruct') { 
     has uint32 $.tv_sec; 
     has long $.tv_nanosecs; 
 } 
 
 sub clock_gettime(uint32 $clock-id, timespec $tspec --> uint32) is native { * }; 
 
 my timespec $this-time .=new; 
 
 my $result = clock_gettime( 0, $this-time); 
 
 say "$result, $this-time"; # OUTPUT: «0, timespec<65385480>␤» 

The original function we are calling, clock_gettime, uses a pointer to the timespec struct as second argument. We declare it as a class here, but specify its representation as is repr('CStruct'), to indicate it corresponds to a C data structure. When we create an object of that class, we are creating exactly the kind of pointer clock_gettime expects. This way, data can be transferred seamlessly to and from the native interface.

Basic use of Pointers

When the signature of your native function needs a pointer to some native type (int32, uint32, etc.) all you need to do is declare the argument is rw :

use NativeCall;
# C prototype is void my_version(int *major, int *minor)
sub my_version(int32 is rw, int32 is rw) is native('foo') { * }
my_version(my int32 $major, my int32 $minor); # Pass a pointer to

Sometimes you need to get a pointer (for example, a library handle) back from a C library. You don't care about what it points to - you just need to keep hold of it. The Pointer type provides for this.

use NativeCall;
sub Foo_init() returns Pointer is native("foo") { * }
sub Foo_free(Pointer) is native("foo") { * }

This works out OK, but you may fancy working with a type named something better than Pointer. It turns out that any class with the representation "CPointer" can serve this role. This means you can expose libraries that work on handles by writing a class like this:

use NativeCall; 
 
 class FooHandle is repr('CPointer') { 
     # Here are the actual NativeCall functions. 
     sub Foo_init() returns FooHandle is native("foo") { * } 
     sub Foo_free(FooHandle) is native("foo") { * } 
     sub Foo_query(FooHandle, Str) returns int8 is native("foo") { * } 
     sub Foo_close(FooHandle) returns int8 is native("foo") { * } 
 
     # Here are the methods we use to expose it to the outside world. 
     method new { 
         Foo_init(); 
     } 
 
     method query(Str $stmt) { 
         Foo_query(self, $stmt); 
     } 
 
     method close { 
         Foo_close(self); 
     } 
 
     # Free data when the object is garbage collected. 
     submethod DESTROY { 
         Foo_free(self); 
     } 
 } 

Note that the CPointer representation can do nothing more than hold a C pointer. This means that your class cannot have extra attributes. However, for simple libraries this may be a neat way to expose an object oriented interface to it.

Of course, you can always have an empty class:

class DoorHandle is repr('CPointer') { }

And just use the class as you would use Pointer, but with potential for better type safety and more readable code.

Once again, type objects are used to represent NULL pointers.

Function Pointers

C libraries can expose pointers to C functions as return values of functions and as members of Structures like, e.g., structs and unions.

Example of invoking a function pointer "$fptr" returned by a function "f", using a signature defining the desired function parameters and return value:

sub f() returns Pointer is native('mylib') { * } 
 
 my $fptr    = f(); 
 my &newfunc = nativecast(:(Str, size_t --> int32), $fptr); 
 
 say newfunc("test", 4); 

Arrays

NativeCall has some support for arrays. It is constrained to work with machine-size integers, doubles and strings, sized numeric types, arrays of pointers, arrays of structs, and arrays of arrays.

Perl 6 arrays, which support amongst other things laziness, are laid out in memory in a radically different way to C arrays. Therefore, the NativeCall library offers a much more primitive CArray type, which you must use if working with C arrays.

Here is an example of passing a C array.

sub RenderBarChart(Str, int32, CArray[Str], CArray[num64]) is native("chart") { * } 
 my @titles := CArray[Str].new; 
 @titles[0]  = 'Me'; 
 @titles[1]  = 'You'; 
 @titles[2]  = 'Hagrid'; 
 my @values := CArray[num64].new; 
 @values[0]  = 59.5e0; 
 @values[1]  = 61.2e0; 
 @values[2]  = 180.7e0; 
 RenderBarChart('Weights (kg)', 3, @titles, @values); 

Note that binding was used to @titles, not assignment! If you assign, you are putting the values into a Perl 6 array, and it will not work out. If this all freaks you out, forget you ever knew anything about the @ sigil and just use $ all the way when using NativeCall.

use NativeCall;
my $titles = CArray[Str].new;
$titles[0] = 'Me';
$titles[1] = 'You';
$titles[2] = 'Hagrid';

Getting return values for arrays works out just the same.

Some library APIs may take an array as a buffer that will be populated by the C function and, for instance, return the actual number of items populated:

use NativeCall;
sub get_n_ints(CArray[int32], int32) returns int32 is native('ints') { * }

In these cases it is important that the CArray has at least the number of elements that are going to be populated before passing it to the native subroutine, otherwise the C function may stomp all over Perl's memory leading to possibly unpredictable behaviour:

my $number_of_ints = 10; 
 my $ints = CArray[int32].allocate($number_of_ints); # instantiates an array with 10 elements 
 my $n = get_n_ints($ints, $number_of_ints); 

Note: allocate was introduced in Rakudo 2018.05. Before that, you had to use this mechanism to extend an array to a number of elements:

my $ints = CArray[int32].new; 
 my $number_of_ints = 10; 
 $ints[$number_of_ints - 1] = 0; # extend the array to 10 items 

The memory management of arrays is important to understand. When you create an array yourself, then you can add elements to it as you wish and it will be expanded for you as required. However, this may result in it being moved in memory (assignments to existing elements will never cause this, however). This means you'd best know what you're doing if you twiddle with an array after passing it to a C library.

By contrast, when a C library returns an array to you, then the memory can not be managed by NativeCall, and it doesn't know where the array ends. Presumably, something in the library API tells you this (for example, you know that when you see a null element, you should read no further). Note that NativeCall can offer you no protection whatsoever here - do the wrong thing, and you will get a segfault or cause memory corruption. This isn't a shortcoming of NativeCall, it's the way the big bad native world works. Scared? Here, have a hug. Good luck!

CArray methods

Besides the usual methods available on every Perl 6 instance, CArray provides the following methods that can be used to interact with the it from the Perl 6 point of view:

As an example, consider the following simple piece of code:

use NativeCall; 
 
 my $native-array = CArray[int32].new( 1, 2, 3, 4, 5 ); 
 say 'Number of elements: ' ~ $native-array.elems; 
 
 # walk the array 
 for $native-array.list -> $elem { 
     say "Current element is: $elem"; 
 } 
 
 # get every element by its index-based position 
 for 0..$native-array.elems - 1 -> $position { 
     say "Element at position $position is " 
           ~ $native-array.AT-POS( $position ); 
 } 
 

that produces the following output

  Number of elements: 5 
   Current element is: 1 
   Current element is: 2 
   Current element is: 3 
   Current element is: 4 
   Current element is: 5 
   Element at position 0 is 1 
   Element at position 1 is 2 
   Element at position 2 is 3 
   Element at position 3 is 4 
   Element at position 4 is 5 

Structs

Thanks to representation polymorphism, it's possible to declare a normal looking Perl 6 class that, under the hood, stores its attributes in the same way a C compiler would lay them out in a similar struct definition. All it takes is a quick use of the "repr" trait:

class Point is repr('CStruct') {
    has num64 $.x;
    has num64 $.y;
}

The attributes can only be of the types that NativeCall knows how to marshal into struct fields. Currently, structs can contain machine-sized integers, doubles, strings, and other NativeCall objects (CArrays, and those using the CPointer and CStruct reprs). Other than that, you can do the usual set of things you would with a class; you could even have some of the attributes come from roles or have them inherited from another class. Of course, methods are completely fine too. Go wild!

CStruct objects are passed to native functions by reference and native functions must also return CStruct objects by reference. The memory management rules for these references are very much like the rules for arrays, though simpler since a struct is never resized. When you create a struct, the memory is managed for you and when the variable(s) pointing to the instance of a CStruct go away, the memory will be freed when the GC gets to it. When a CStruct-based type is used as the return type of a native function, the memory is not managed for you by the GC.

NativeCall currently doesn't put object members in containers, so assigning new values to them (with =) doesn't work. Instead, you have to bind new values to the private members:

class MyStruct is repr('CStruct') { 
     has CArray[num64] $!arr; 
     has Str $!str; 
     has Point $!point; # Point is a user-defined class 
 
     submethod TWEAK { 
         my $arr := CArray[num64].new; 
         $arr[0] = 0.9e0; 
         $arr[1] = 0.2e0; 
         $!arr := $arr; 
         $!str := 'Perl 6 is fun'; 
         $!point := Point.new; 
     } 
 } 

As you may have predicted by now, a NULL pointer is represented by the type object of the struct type.

CUnions

Likewise, it is possible to declare a Perl 6 class that stores its attributes the same way a C compiler would lay them out in a similar union definition; using the CUnion representation:

use NativeCall; 
 
 class MyUnion is repr('CUnion') { 
     has int32 $.flags32; 
     has int64 $.flags64; 
 } 
 
 say nativesizeof(MyUnion.new);  # 8, ie. max(sizeof(MyUnion.flags32), sizeof(MyUnion.flags64)) 

Embedding CStructs and CUnions

CStructs and CUnions can be in turn referenced by—or embedded into—a surrounding CStruct and CUnion. To say the former we use has as usual, and to do the latter we use the HAS declarator instead:

class MyStruct is repr('CStruct') { 
     has Point $.point;  # referenced 
     has int32 $.flags; 
 } 
 
 say nativesizeof(MyStruct.new);  # 16, ie. sizeof(struct Point *) + sizeof(int32_t) 
 
 class MyStruct2 is repr('CStruct') { 
     HAS Point $.point;  # embedded 
     has int32 $.flags; 
 } 
 
 say nativesizeof(MyStruct2.new);  # 24, ie. sizeof(struct Point) + sizeof(int32_t) 

Notes on Memory management

When allocating a struct for use as a struct, make sure that you allocate your own memory in your C functions. If you're passing a struct into a C function which needs a Str/char* allocated ahead of time, be sure to assign a container for a variable of type Str prior to passing your struct into the function.

In your Perl6 code...

class AStringAndAnInt is repr("CStruct") { 
   has Str $.a_string; 
   has int32 $.an_int32; 
 
   sub init_struct(AStringAndAnInt is rw, Str, int32) is native('simple-struct') { * } 
 
   submethod BUILD(:$a_string, :$an_int) { 
     init_struct(self, $a_string, $an_int); 
   } 
 } 
 

In this code we first set up our members, $.a_string and $.an_int32. After that we declare our init_struct() function for the init() method to wrap around; this function is then called from BUILD to effectively assign the values before returning the created object.

In your C code...

typedef struct a_string_and_an_int32_t_ { 
   char *a_string; 
   int32_t an_int32; 
 } a_string_and_an_int32_t; 
 

Here's the structure. Notice how we've got a char * there.

void init_struct(a_string_and_an_int32_t *target, char *str, int32_t int32) { 
   target->an_int32 = int32; 
   target->a_string = strdup(str); 
 
   return; 
 } 
 

In this function we initialize the C structure by assigning an integer by value, and passing the string by reference. The function allocates memory that it points <char *a_string> to within the structure as it copies the string. (Note you will also have to manage deallocation of the memory as well to avoid memory leaks.)

# A long time ago in a galaxy far, far away... 
 my $foo = AStringAndAnInt.new(a_string => "str", an_int => 123); 
 say "foo is {$foo.a_string} and {$foo.an_int32}"; 
 # OUTPUT: «foo is str and 123␤» 

Typed Pointers

You can type your Pointer by passing the type as a parameter. It works with the native type but also with CArray and CStruct defined types. NativeCall will not implicitly allocate the memory for it even when calling new on them. It's mostly useful in the case of a C routine returning a pointer, or if it's a pointer embedded in a CStruct.

use NativeCall; 
 sub strdup(Str $s --> Pointer[Str]) is native {*} 
 my Pointer[Str] $p = strdup("Success!"); 
 say $p.deref; 

You have to call .deref on Pointers to access the embedded type. In the example above, declaring the type of the pointer avoids typecasting error when dereferenced. Please note that the original strdup returns a pointer to char; we are using Pointer<Str>.

my Pointer[int32] $p; #For a pointer on int32; 
 my Pointer[MyCstruct] $p2 = some_c_routine(); 
 my MyCstruct $mc = $p2.deref; 
 say $mc.field1; 

It's quite common for a native function to return a pointer to an array of elements. Typed pointers can be dereferenced as an array to obtain individual elements.

my $n = 5; 
 # returns a pointer to an array of length $n 
 my Pointer[Point] $plot = some_other_c_routine($n); 
 # display the 5 elements in the array 
 for 1 .. $n -> $i { 
     my $x = $plot[$i - 1].x; 
     my $y = $plot[$i - 1].y; 
     say "$i: ($x, $y)"; 
 } 

Pointers can also be updated to reference successive elements in the array:

my Pointer[Point] $elem = $plot; 
 # show differences between successive points 
 for 1 ..^ $n { 
     my Point $lo = $elem.deref; 
     ++$elem; # equivalent to $elem = $elem.add(1); 
     my Point $hi = (++$elem).deref; 
     my $dx = $hi.x = $lo.x; 
     my $dy = $hi.y = $lo.y; 
     say "$_: delta ($dx, $dy)"; 
 } 

Void pointers can also be used by declaring them Pointer[void]. Please consult the native types documentation for more information on the subject.

Strings

Explicit memory management

Let's say there is some C code that caches strings passed, like so:

#include <stdlib.h> 
 
 static char *__VERSION; 
 
 char * 
 get_version() 
 { 
     return __VERSION; 
 } 
 
 char * 
 set_version(char *version) 
 { 
     if (__VERSION != NULL) free(__VERSION); 
     __VERSION = version; 
     return __VERSION; 
 } 

If you were to write bindings for get_version and set_version, they would initially look like this, but will not work as intended:

sub get_version(--> Str)     is native('./version') { * } 
 sub set_version(Str --> Str) is native('./version') { * } 
 
 say set_version('1.0.0'); # 1.0.0 
 say get_version;          # Differs on each run 
 say set_version('1.0.1'); # Double free; segfaults 

This code segfaults on the second set_version call because it tries to free the string passed on the first call after the garbage collector had already done so. If the garbage collector shouldn't free a string passed to a native function, use explicitly-manage with it:

say set_version(explicitly-manage('1.0.0')); # 1.0.0 
 say get_version;                             # 1.0.0 
 say set_version(explicitly-manage('1.0.1')); # 1.0.1 
 say get_version;                             # 1.0.1 

Bear in mind all memory management for explicitly managed strings must be handled by the C library itself or through the NativeCall API to prevent memory leaks.

Buffers and blobs

Blobs and Bufs are the Perl 6 way of storing binary data. We can use them for interchange of data with native functions and data structures, although not directly. We will have to use nativecast.

my $blob = Blob.new(0x22, 0x33); 
 my $src = nativecast(Pointer, $blob); 

This $src can then be used as an argument for any native function that takes a Pointer. The opposite, putting values pointed to by a Pointer into a Buf or using it to inialize a Blob is not directly supported. You might want to use NativeHelpers::Blob to do this kind of operations.

my $esponja = blob-from-pointer( $inter, :2elems, :type(Blob[int8])); 
 say $esponja; 

Function arguments

NativeCall also supports native functions that take functions as arguments. One example of this is using function pointers as callbacks in an event-driven system. When binding these functions via NativeCall, one need only provide the equivalent signature as a constraint on the code parameter:

use NativeCall;
# void SetCallback(int (*callback)(const char *))
my sub SetCallback(&callback (Str --> int32)) is native('mylib') { * }

Note: the native code is responsible for memory management of values passed to Perl 6 callbacks this way. In other words, NativeCall will not free() strings passed to callbacks.

Library Paths and Names

The native trait accepts the library name, the full path, or a subroutine returning either of the two. When using the library name, the name is assumed to be prepended with "lib" and appended with ".so" (or just appended with ".dll" on Windows), and will be searched for in the paths in the LD_LIBRARY_PATH (PATH on Windows) environment variable.

    use NativeCall; 
     constant LIBMYSQL = 'mysqlclient'; 
     constant LIBFOO = '/usr/lib/libfoo.so.1'; 
     sub LIBBAR { 
         my $path = qx/pkg-config --libs libbar/.chomp; 
         $path ~~ s/\/[[\w+]+ % \/]/\0\/bar/; 
         $path 
     } 
     # and later 
 
     sub mysql_affected_rows returns int32 is native(LIBMYSQL) {*}; 
     sub bar is native(LIBFOO) {*} 
     sub baz is native(LIBBAR) {*} 

You can also put an incomplete path like './foo' and NativeCall will automatically put the right extension according to the platform specification.

BE CAREFUL: the native trait and constant are evaluated at compile time. Don't write a constant that depends on a dynamic variable like:

# WRONG:
constant LIBMYSQL = %*ENV<P6LIB_MYSQLCLIENT> || 'mysqlclient';

This will keep the value given at compile time. A module will be precompiled and LIBMYSQL will keep the value it acquires when the module gets precompiled.

ABI/API Version

If you write native('foo') NativeCall will search libfoo.so under Unix like system (libfoo.dynlib on OS X, foo.dll on win32). In most modern system it will require you or the user of your module to install the development package because it's recommended to always provide an API/ABI version to a shared library, so libfoo.so ends often being a symbolic link provided only by a development package.

To avoid that, the native trait allows you to specify the API/ABI version. It can be a full version or just a part of it. (Try to stick to Major version, some BSD code does not care for Minor.)

use NativeCall;
sub foo1 is native('foo', v1) {*} # Will try to load libfoo.so.1
sub foo2 is native('foo', v1.2.3) {*} # Will try to load libfoo.so.1.2.3

my List $lib = ('foo', 'v1');
sub foo3 is native($lib) {*}

Routine

The native trait also accepts a Callable as argument, allowing you to provide your own way to handle the way it will find the library file to load.

use NativeCall;
sub foo is native(sub {'libfoo.so.42'}) {*}

It will only be called at the first invocation of the sub.

Calling into the standard library

If you want to call a C function that's already loaded, either from the standard library or from your own program, you can omit the value, so is native.

For example on a UNIX-like operating system, you could use the following code to print the home directory of the current user:

use NativeCall;
my class PwStruct is repr('CStruct') {
    has Str $.pw_name;
    has Str $.pw_passwd;
    has uint32 $.pw_uid;
    has uint32 $.pw_gid;
    has Str $.pw_gecos;
    has Str $.pw_dir;
    has Str $.pw_shell;
}
sub getuid()              returns uint32   is native { * };
sub getpwuid(uint32 $uid) returns PwStruct is native { * };

say getpwuid(getuid()).pw_dir;

Though of course $*HOME is a much easier way :-)

Exported variables

Variables exported by a library – also named "global" or "extern" variables – can be accessed using cglobal. For example:

my $var := cglobal('libc.so.6', 'errno', int32) 

This code binds to $var a new Proxy object that redirects all its accesses to the integer variable named "errno" as exported by the "libc.so.6" library.

C++ Support

NativeCall offers support to use classes and methods from C++ as shown in https://github.com/rakudo/rakudo/blob/master/t/04-nativecall/13-cpp-mangling.t (and its associated C++ file). Note that at the moment it's not as tested and developed as C support.

Helper Functions

The NativeCall library exports several subroutines to help you work with data from native libraries.

sub nativecast

sub nativecast($target-type, $source) is export(:DEFAULT)

This will cast the Pointer $source to an object of $target-type. The source pointer will typically have been obtained from a call to a native subroutine that returns a pointer or as a member of a struct, this may be specified as void * in the C library definition for instance, but you may also cast from a pointer to a less specific type to a more specific one.

As a special case, if a Signature is supplied as $target-type then a subroutine will be returned which will call the native function pointed to by $source in the same way as a subroutine declared with the native trait. This is described in Function Pointers.

sub cglobal

sub cglobal($libname, $symbol, $target-type) is export is rw

This returns a Proxy object that provides access to the extern named $symbol that is exposed by the specified library. The library can be specified in the same ways that they can be to the native trait.

sub nativesizeof

sub nativesizeof($obj) is export(:DEFAULT)

This returns the size in bytes of the supplied object, it can be thought of as being equivalent to sizeof in C. The object can be a builtin native type such as int64 or num64, a CArray or a class with the repr CStruct, CUnion or CPointer.

sub explicitly-manage

sub explicitly-manage($str) is export(:DEFAULT)

This returns a CStr object for the given Str. If the string returned is passed to a NativeCall subroutine, it will not be freed by the runtime's garbage collector.

Examples

Some specific examples, and instructions to use examples above in particular platforms.

PostgreSQL

The PostgreSQL examples in DBIish make use of the NativeCall library and is native to use the native _putenv function call in Windows.

MySQL

NOTE: Please bear in mind that, under the hood, Debian has substituted MySQL with MariaDB since the Stretch version, so if you want to install MySQL, use MySQL APT repository instead of the default repository.

To use the MySQL example in DBIish, you'll need to install MySQL server locally; on Debian-esque systems it can be installed with something like:

wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb 
 sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb # Don't forget to select 5.6.x 
 sudo apt-get update 
 sudo apt-get install mysql-community-server -y 
 sudo apt-get install libmysqlclient18 -y 

Prepare your system along these lines before trying out the examples:

$ mysql -u root -p 
 SET PASSWORD = PASSWORD('sa'); 
 DROP DATABASE test; 
 CREATE DATABASE test; 

Microsoft Windows

Here is an example of a Windows API call:

use NativeCall; 
 
 sub MessageBoxA(int32, Str, Str, int32) 
     returns int32 
     is native('user32') 
     { * } 
 
 MessageBoxA(0, "We have NativeCall", "ohai", 64); 

Short Tutorial on calling a C function

This is an example for calling a standard function and using the returned information in a Perl 6 program.

getaddrinfo is a POSIX standard function for obtaining network information about a network node, e.g., google.com. It is an interesting function to look at because it illustrates a number of the elements of NativeCall.

The Linux manual provides the following information about the C callable function:

int getaddrinfo(const char *node, const char *service, 
        const struct addrinfo *hints, 
        struct addrinfo **res); 

The function returns a response code 0 = error, 1 = success. The data are extracted from a linked list of addrinfo elements, with the first element pointed to by res.

From the table of NativeCall Types we know that an int is int32. We also know that a char * is one of the forms C for a C Str, which maps simply to Str. But addrinfo is a structure, which means we will need to write our own Type class. However, the function declaration is straightforward:

sub getaddrinfo( Str $node, Str $service, Addrinfo $hints, Pointer $res is rw ) 
     returns int32 
     is native 
     { * } 

Note that $res is to be written by the function, so it must be labeled as rw. Since the library is standard POSIX, the library name can be the Type definition or null.

We now have to handle structure Addrinfo. The Linux Manual provides this information:

struct addrinfo { 
                int              ai_flags; 
                int              ai_family; 
                int              ai_socktype; 
                int              ai_protocol; 
                socklen_t        ai_addrlen; 
                struct sockaddr *ai_addr; 
                char            *ai_canonname; 
                struct addrinfo *ai_next; 
            }; 

The int, char* parts are straightforward. Some research indicates that socklen_t can be architecture dependent, but is an unsigned integer of at least 32 bits. So socklen_t can be mapped to the uint32 type.

The complication is sockaddr which differs depending on whether ai_socktype is undefined, INET, or INET6 (a standard v4 IP address or a v6 address).

So we create a Perl 6 class to map to the C struct addrinfo; while we're at it, we also create another class for SockAddr which is needed for it.

class SockAddr is repr('CStruct') { 
     has int32    $.sa_family; 
     has Str      $.sa_data; 
 } 
 
 class Addrinfo is repr('CStruct') { 
     has int32     $.ai_flags; 
     has int32     $.ai_family; 
     has int32     $.ai_socktype; 
     has int32     $.ai_protocol; 
     has int32     $.ai_addrlen; 
     has SockAddr  $.ai_addr       is rw; 
     has Str       $.ai_cannonname is rw; 
     has Addrinfo  $.ai_next       is rw; 
 
 } 

The is rw on the last three attributes reflects that these were defined in C to be pointers.

The important thing here for mapping to a C Struct is the structure of the state part of the class, that is the attributes. However, a class can have methods and NativeCall does not 'touch' them for mapping to C. This means that we can add extra methods to the class to unpack the attributes in a more readable manner, e.g.,

method flags { 
     do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 
 } 

By defining an appropriate enum, flags will return a string of keys rather than a bit packed integer.

The most useful information in the sockaddr structure is the address of node, which depends on the family of the Socket. So we can add method address to the Perl 6 class that interprets the address depending on the family.

In order to get a human readable IP address, there is the C function inet_ntop which returns a char * given a buffer with the addrinfo.

Putting all these together, leads to the following program:

#!/usr/bin/env perl6 
 
 use v6; 
 use NativeCall; 
 
 constant \INET_ADDRSTRLEN = 16; 
 constant \INET6_ADDRSTRLEN = 46; 
 
 enum AddrInfo-Family ( 
     AF_UNSPEC                   => 0; 
     AF_INET                     => 2; 
     AF_INET6                    => 10; 
 ); 
 
 enum AddrInfo-Socktype ( 
     SOCK_STREAM                 => 1; 
     SOCK_DGRAM                  => 2; 
     SOCK_RAW                    => 3; 
     SOCK_RDM                    => 4; 
     SOCK_SEQPACKET              => 5; 
     SOCK_DCCP                   => 6; 
     SOCK_PACKET                 => 10; 
 ); 
 
 enum AddrInfo-Flags ( 
     AI_PASSIVE                  => 0x0001; 
     AI_CANONNAME                => 0x0002; 
     AI_NUMERICHOST              => 0x0004; 
     AI_V4MAPPED                 => 0x0008; 
     AI_ALL                      => 0x0010; 
     AI_ADDRCONFIG               => 0x0020; 
     AI_IDN                      => 0x0040; 
     AI_CANONIDN                 => 0x0080; 
     AI_IDN_ALLOW_UNASSIGNED     => 0x0100; 
     AI_IDN_USE_STD3_ASCII_RULES => 0x0200; 
     AI_NUMERICSERV              => 0x0400; 
 ); 
 
 sub inet_ntop(int32, Pointer, Blob, int32 --> Str) 
     is native {} 
 
 class SockAddr is repr('CStruct') { 
     has uint16 $.sa_family; 
 } 
 
 class SockAddr-in is repr('CStruct') { 
     has int16 $.sin_family; 
     has uint16 $.sin_port; 
     has uint32 $.sin_addr; 
 
     method address { 
         my $buf = buf8.allocate(INET_ADDRSTRLEN); 
         inet_ntop(AF_INET, Pointer.new(nativecast(Pointer,self)+4), 
             $buf, INET_ADDRSTRLEN) 
     } 
 } 
 
 class SockAddr-in6 is repr('CStruct') { 
     has uint16 $.sin6_family; 
     has uint16 $.sin6_port; 
     has uint32 $.sin6_flowinfo; 
     has uint64 $.sin6_addr0; 
     has uint64 $.sin6_addr1; 
     has uint32 $.sin6_scope_id; 
 
     method address { 
         my $buf = buf8.allocate(INET6_ADDRSTRLEN); 
         inet_ntop(AF_INET6, Pointer.new(nativecast(Pointer,self)+8), 
             $buf, INET6_ADDRSTRLEN) 
     } 
 } 
 
 class Addrinfo is repr('CStruct') { 
     has int32 $.ai_flags; 
     has int32 $.ai_family; 
     has int32 $.ai_socktype; 
     has int32 $.ai_protocol; 
     has uint32 $.ai_addrNativeCalllen; 
     has SockAddr $.ai_addr is rw; 
     has Str $.ai_cannonname is rw; 
     has Addrinfo $.ai_next is rw; 
 
     method flags { 
         do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 
     } 
 
     method family { 
         AddrInfo-Family($!ai_family) 
     } 
 
     method socktype { 
         AddrInfo-Socktype($!ai_socktype) 
     } 
 
     method address { 
         given $.family { 
             when AF_INET { 
                 nativecast(SockAddr-in, $!ai_addr).address 
             } 
             when AF_INET6 { 
                 nativecast(SockAddr-in6, $!ai_addr).address 
             } 
         } 
     } 
 } 
 
 sub getaddrinfo(Str $node, Str $service, Addrinfo $hints, 
                 Pointer $res is rw --> int32) 
     is native {}; 
 
 sub freeaddrinfo(Pointer) 
     is native {} 
 
 sub MAIN() { 
     my Addrinfo $hint .= new(:ai_flags(AI_CANONNAME)); 
     my Pointer $res .= new; 
     my $rv = getaddrinfo("google.com", Str, $hint, $res); 
     say "return val: $rv"; 
     if ( ! $rv ) { 
         my $addr = nativecast(Addrinfo, $res); 
         while $addr { 
             with $addr { 
                 say "Name: ", $_ with .ai_cannonname; 
                 say .family, ' ', .socktype; 
                 say .address; 
                 $addr = .ai_next; 
             } 
         } 
     } 
     freeaddrinfo($res); 
 } 

This produces the following output:

return val: 0 
 Name: google.com 
 AF_INET SOCK_STREAM 
 216.58.219.206 
 AF_INET SOCK_DGRAM 
 216.58.219.206 
 AF_INET SOCK_RAW 
 216.58.219.206 
 AF_INET6 SOCK_STREAM 
 2607:f8b0:4006:800::200e 
 AF_INET6 SOCK_DGRAM 
 2607:f8b0:4006:800::200e 
 AF_INET6 SOCK_RAW 
 2607:f8b0:4006:800::200e 

38 Perl 6 native types

Using the types the compiler and hardware make available to you

Perl 6 offers a set of native types with a fixed, and known, representation in memory. This page shows which ones exist and how they can be used. Please check also the page on native numerics for more information on them.

Types with native representation

Some simple types in Perl 6 have a native representation, indicating that they will use the C language representation provided by the compiler, operating system and machine. These are the four native types available:

int Equivalent to Int
uint Equivalent to Int with the unsigned trait
num Equivalent to Num
str Equivalent to Str

However, these types do not necessarily have the size that is required by the NativeCall interface (e.g., Perl 6's int can be 8 bytes but C's int is only 4 bytes). Instead, the types below will have to be used instead of the types int or num listed above.

In general, these variables will behave in the same way as regular scalar variables, in a behavior that is called auto-boxing; however, there are some differences, since what you are actually declaring is how they will be represented, not their actual type. The first one is that their type will be actually their equivalent type, not their native type.

my int $intillo = 3;
say $intillo.^name; # OUTPUT: «Int␤»

This obviously means that they will smartmatch their equivalent, not their native type:

my str $strillo = "tres";
say $strillo ~~ str; # OUTPUT: «False␤»
say $strillo ~~ Str; # OUTPUT: «True␤»

This is due to the fact that Natives don't know their types because they're just values, without any meta-data.

They cannot be bound either. Trying to do my num $numillo := 3.5 will raise the exception Cannot bind to natively typed variable '$variable-name'; use assignment instead.

Types with native representation and size

What has been mentioned about types with native representation also applies here; they will be auto-boxed to Perl 6 types and will not be boundable. However, these types, which are listed in the table below, have the characteristic of being usable in NativeCall functions.

int8 (int8_t in C, also used for char)
int16 (int16_t in C, also used for short)
int32 (int32_t in C, also used for int)
int64 (int64_t in C)
byte, uint8 (uint8_t in C, also used for unsigned char)
uint16 (uint16_t in C, also used for unsigned short)
uint32 (uint32_t in C, also used for unsigned int)
uint64 (uint64_t in C)
num32 (float in C)
num64 (double in C)

These types have a fixed size representation which is independent of the platform, and thus can be used safely for those native calls. Nothing prevents us from using them in any other environment, if we so wish. In the same way as the types above, this size will have to be taken into account when assigning values to variables of this type:

my byte $intillo = 257;
say $intillo; # OUTPUT: «1␤»

Since byte is able to hold only 8 bits, it will wrap over and assign the result of the original value modulo 256, which is what is shown.

The main difference between types with declared native size and those without is the use of is nativesize in their declaration. For instance, int8 is declared in this way:

my native int8 is repr('P6int') is Int is nativesize( 8) { }

Indicating that it will use, besides an integer representation (P6int), a native size of only 8 bits. This trait, however, is not intended to be used in your programs since it is not part of the Perl 6 specification.

The void type

The native void type corresponds to the C void type. Although, being a valid type, you can use it in expressions:

use NativeCall;
my void $nothing;
say $nothing.perl; # OUTPUT: «NativeCall::Types::void␤»

In practice, it is an Uninstantiable type that can rarely be used by itself, and in fact it is explicitly forbidden in return types. However, it is generally found in typed pointers representing the equivalent to the void * pointer in C.

sub malloc( int32 $size --> Pointer[void] ) is native { * }; 
 my Pointer[void] $for-malloc = malloc( 32 ); 
 say $for-malloc.perl; 

You can also nativecast Blobs to this kind of pointer in case you need to work with them in native functions that use the type

use NativeCall; 
 my Pointer[void] $native = nativecast(Pointer[void], Blob.new(0x22, 0x33)); 

However, outside that, the functionality it offers is quite limited, since pointers to void cannot be dereferenced:

use NativeCall; 
 my Pointer[void] $native = nativecast(Pointer[void], Buf.new(0x22, 0x33)); 
 say $native.deref; # ERROR OUTPUT: «Internal error: unhandled target type␤» 

Atomic types

In this context, atomic refers to safe operation under threading. Perl 6 provides a type, atomicint, and some operations which, together, guarantee this. Please check the atomic operations section on the Numerics page for more information on this.

Rakudo specific types

The types described in this section are Rakudo specific, so they are not guaranteed to be in other implementations or remain the same in future versions. Test code that uses them heavily.

long (long in C)
longlong (longlong in C)
ulong (long and unsigned in C)
ulonglong (longlong and unsigned in C)
size_t (size_t and unsigned in C)
ssize_t (size_t in C)
bool (bool in C)

You can use them in the same way they would be used in native C:

use NativeCall; 
 
 my $just-an-array = CArray[int32].new( 1, 2, 3, 4, 5 ); 
 
 loop ( my size_t $i = 0; $i < $just-an-array.elems; $i++ ) { 
     say $just-an-array[$i]; 
 } 

Which would print the five elements of the array, as it should be expected.

39 Newline handling in Perl 6

How the different newline characters are handled, and how to change the behavior

Different operating systems use different characters, or combinations of them, to represent the transition to a new line. Every language has its own set of rules to handle this. Perl 6 has the following ones:

You can change the default behavior for a particular handle by setting the :nl-out attribute when you create that handle.

my $crlf-out = open(IO::Special.new('<STDOUT>'), :nl-out("\\\n\r"));
$*OUT.say: 1;     #OUTPUT: «1␤»
$crlf-out.say: 1; #OUTPUT: «1\␤␍»

In this example, where we are replicating standard output to a new handle by using IO::Special, we are appending a \ to the end of the string, followed by a newline and a carriage return ; everything we print to that handle will get those characters at the end of the line, as shown.

In regular expressions, \n is defined in terms of the Unicode definition of logical newline. It will match . and also \v, as well as any class that includes whitespace.

40 Numerics

Numeric types available in Perl 6

Int

The Int type offers arbitrary-size integer numbers. They can get as big as your computer memory allows, although some implementations choose to throw a numeric overflow error when asked to produce integers of truly staggering size:

say 10**600**600 
 # OUTPUT: «Numeric overflow␤» 

Unlike some languages, division performed using / operator when both operands are of Int type, would produce a fractional number, without any rounding performed.

say 4/5; # OUTPUT: «0.8␤» 

The type produced by this division is either a Rat or a Num type. The Rat is produced if, after reduction, the fraction's denominator is smaller than 64 bits, otherwise a Num type is produced.

The div and narrow routines can be helpful if you wish to end up with an Int result, whenever possible. The div operator performs integer division, discarding the remainder, while narrow fits the number into the narrowest type it'll fit:

say 5 div 2; # OUTPUT: «2␤» 
 
 # Result `2` is narrow enough to be an Int: 
 say (4/2).narrow; # OUTPUT: «2␤» 
 say (4/2).narrow.^name; # OUTPUT: «Int␤» 
 
 # But 2.5 has fractional part, so it ends up being a Rat type: 
 say (5/2).narrow.^name; # OUTPUT: «Rat␤» 
 say (5/2).narrow;       # OUTPUT: «2.5␤» 
 
 # Denominator is too big for a Rat, so a Num is produced: 
 say 1 / 10⁹⁹; # OUTPUT: «1e-99␤» 

Perl 6 has FatRat type that offers arbitrary precision fractions. How come a limited-precision Num is produced instead of a FatRat type in the last example above? The reason is: performance. Most operations are fine with a little bit of precision lost and so do not require the use of a more expensive FatRat type. You'll need to instantiate one yourself if you wish to have the extra precision.

Num

The Num type offers double-precision floating-point decimal numbers, sometimes called "doubles" in other languages.

A Num literal is written with the exponent separated using the letter e. Keep in mind that the letter e is required even if the exponent is zero, as otherwise you'll get a Rat rational literal instead:

say 42e0.^name; # OUTPUT: «Num␤» 
 say 42.0.^name; # OUTPUT: «Rat␤» 

Case-sensitive words Inf and NaN represent the special values infinity and not-a-number respectively. The U+221E INFINITY () character can be used instead of Inf:

Perl 6 follows the IEEE 754-2008 Standard for Floating-Point Arithmetic as much as possible, with more conformance planned to be implemented in later language versions. The language guarantees the closest representable number is chosen for any given Num literal and does offer support for negative zero and denormals (also known as "subnormals").

Keep in mind that output routines like say or put do not try very hard to distinguish between how Numeric types are output and may choose to display a Num as an Int or a Rat number. For a more definitive string to output, use the perl method:

say  1e0;      # OUTPUT: «1␤» 
 say .5e0;      # OUTPUT: «0.5␤» 
 say  1e0.perl; # OUTPUT: «1e0␤» 
 say .5e0.perl; # OUTPUT: «0.5e0␤» 

Complex

The Complex type numerics of the complex plane. The Complex objects consist of two Num objects representing the real and imaginary portions of the complex number.

To create a Complex, you can use the postfix i operator on any other non-complex number, optionally setting the real part with addition. To use the i operator on NaN or Inf literals, separate it from them with a backslash.

say 42i;      # OUTPUT: «0+42i␤» 
 say 73+42i;   # OUTPUT: «73+42i␤» 
 say 73+Inf\i; # OUTPUT: «73+Inf\i␤» 

Keep in mind the above syntax is just an addition expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.

# Precedence of `*` is higher than that of `+` 
 say 2 * 73+10i; # OUTPUT: «146+10i␤» 

To avoid these issues, you can choose to use the Complex literal syntax instead, which involves surrounding the real and imaginary parts with angle brackets, without any spaces:

say 2 * <73+10i>; # OUTPUT: «146+20i␤» 
 
 multi how-is-it (<2+4i>) { say "that's my favorite number!" } 
 multi how-is-it (|)      { say "meh"                        } 
 how-is-it 2+4i;  # OUTPUT: «that's my favorite number!␤» 
 how-is-it 3+2i;  # OUTPUT: «meh␤» 

Rational

The types that do the Rational role offer high-precision and arbitrary-precision decimal numbers. Since the higher the precision the larger the performance penalty, the Rational types come in two flavours: Rat and FatRat. The Rat is the most often-used variant that degrades into a Num in most cases, when it can no longer hold all of the requested precision. The FatRat is the arbitrary-precision variant that keeps growing to provide all of the requested precision.

Rat

The most common of Rational types. It supports rationals with denominators as large as 64 bits (after reduction of the fraction to the lowest denominator). Rat objects with larger denominators can be created directly, however, when Rats with such denominators are the result of mathematical operations, they degrade to a Num object.

The Rat literals use syntax similar to Num literals in many other languages, using the dot to indicate the number is a decimal:

say .1 + .2 == .3; # OUTPUT: «True␤» 

If you try to execute a statement similar to the above in many common languages, you'll get False as the answer, due to imprecision of floating point math. To get the same result in Perl 6, you'd have to use Num literals instead:

say .1e0 + .2e0 == .3e0; # OUTPUT: «False␤» 

You can also use / division operator with Int or Rat objects to produce a Rat:

say 3/4;     # OUTPUT: «0.75␤» 
 say 3/4.2;   # OUTPUT: «0.714286␤» 
 say 1.1/4.2; # OUTPUT: «0.261905␤» 

Keep in mind the above syntax is just a division expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.

# Precedence of power operators is higher than division 
 say 3/2²; # OUTPUT: «0.75␤» 

To avoid these issues, you can choose to use the Rational literal syntax instead, which involves surrounding the numerator and denominator with angle brackets, without any spaces:

say <3/2>²; # OUTPUT: «2.25␤» 
 
 multi how-is-it (<3/2>) { say "that's my favorite number!" } 
 multi how-is-it (|)     { say "meh"                        } 
 how-is-it 3/2;  # OUTPUT: «that's my favorite number!␤» 
 how-is-it 1/3;  # OUTPUT: «meh␤» 

Lastly, any Unicode character with property No that represents a fractional number can be used as a Rat literal:

say ½ + ⅓ + ⅝ + ⅙; # OUTPUT: «1.625␤» 

Degradation to Num

If a mathematical operation that produces a Rat answer would produce a Rat with denominator larger than 64 bits, that operation would instead return a Num object. When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a "fattish" Rat with larger denominator will be created.

FatRat

The last Rational type—FatRat—keeps all of the precision you ask of it, storing the numerator and denominator as two Int objects. A FatRat is more infectious than a Rat, so many math operations with a FatRat will produce another FatRat, preserving all of the available precision. Where a Rat degrades to a Num, math with a FatRat keeps chugging along:

say ((42 + Rat.new(1,2))/999999999999999999).^name;         # OUTPUT: «Rat␤» 
 say ((42 + Rat.new(1,2))/9999999999999999999).^name;        # OUTPUT: «Num␤» 
 say ((42 + FatRat.new(1,2))/999999999999999999).^name;      # OUTPUT: «FatRat␤» 
 say ((42 + FatRat.new(1,2))/99999999999999999999999).^name; # OUTPUT: «FatRat␤» 

There's no special operator or syntax available for construction of FatRat objects. Simply use FatRat.new method, giving numerator as first positional argument and denominator as the second.

If your program requires a significant amount of FatRat creation, you could create your own custom operator:

sub infix:<🙼> { FatRat.new: $^a, $^b } 
 say (1🙼3).perl; # OUTPUT: «FatRat.new(1, 3)␤» 

Printing Rationals

Keep in mind that output routines like say or put do not try very hard to distinguish between how Numeric types are output and may choose to display a Num as an Int or a Rat number. For a more definitive string to output, use the perl method:

say 1.0;        # OUTPUT: «1␤» 
 say ⅓;          # OUTPUT: «0.333333␤» 
 say 1.0.perl;   # OUTPUT: «1.0␤» 
 say ⅓.perl;     # OUTPUT: «<1/3>␤» 

For even more information, you may choose to see the Rational object in the nude, displaying its numerator and denominator:

say ⅓;          # OUTPUT: «0.333333␤» 
 say 4/2;        # OUTPUT: «2␤» 
 say ⅓.perl;     # OUTPUT: «<1/3>␤» 
 say <4/2>.nude; # OUTPUT: «(2 1)␤» 

Division By Zero

In many languages division by zero is an immediate exception. In Perl 6, what happens depends on what you're dividing and how you use the result.

Perl 6 follows IEEE 754-2008 Standard for Floating-Point Arithmetic, but for historical reasons 6.c language does not comply fully. Num division by zero produces a Failure, while Complex division by zero produces NaN components, regardless of what the numerator is.

As of 6.d language, both Num and Complex division by zero will produce a -Inf, +Inf, or NaN depending on whether the numerator was negative, positive, or zero, respectively (for Complex the real and imaginary components are Num and are considered separately).

Division of Int numerics produces a Rat object (or a Num, if after reduction the denominator is larger than 64-bits, which isn't the case when you're dividing by zero). This means such division never produces an Exception or a Failure. The result is a Zero-Denominator Rational, which can be explosive.

Zero-Denominator Rationals

A Zero-Denominator Rational is a numeric that does role Rational, which among core numerics would be Rat and FatRat objects, which has denominator of zero.

Operations that can be performed without requiring actual division to occur are non-explosive. For example, you can separately examine numerator and denominator in the nude or perform mathematical operations without any exceptions or failures popping up.

Converting zero-denominator rationals to Num follows the IEEE conventions, and the result is a -Inf, Inf, or NaN, depending on whether the numerator is negative, positive, or zero, respectively. The same is true going the other way: converting ±Inf/NaN to one of the Rational types will produce a zero-denominator rational with an appropriate numerator:

say  <1/0>.Num;   # OUTPUT: «Inf␤» 
 say <-1/0>.Num;   # OUTPUT: «-Inf␤» 
 say  <0/0>.Num;   # OUTPUT: «NaN␤» 
 say Inf.Rat.nude; # OUTPUT: «(1 0)␤» 

All other operations that require non-IEEE division of the numerator and denominator to occur will result in X::Numeric::DivideByZero exception to be thrown. The most common of such operations would likely be trying to print or stringify a zero-denominator rational:

say 0/0; 
 # OUTPUT: 
 # Attempt to divide by zero using div 
 #  in block <unit> at -e line 1 

Allomorphs

Allomorphs are subclasses of two types that can behave as either of them. For example, the allomorph IntStr is the subclass of Int and Str types and will be accepted by any type constraint that requires an Int or Str object.

Allomorphs can be created using angle brackets, either used standalone or as part of a hash key lookup; directly using method .new and are also provided by some constructs such as parameters of sub MAIN.

say <42>.^name;                 # OUTPUT: «IntStr␤» 
 say <42e0>.^name;               # OUTPUT: «NumStr␤» 
 say < 42+42i>.^name;            # OUTPUT: «ComplexStr␤» 
 say < 1/2>.^name;               # OUTPUT: «RatStr␤» 
 say <0.5>.^name;                # OUTPUT: «RatStr␤» 
 
 @*ARGS = "42"; 
 sub MAIN($x) { say $x.^name }   # OUTPUT: «IntStr␤» 
 
 say IntStr.new(42, "42").^name; # OUTPUT: «IntStr␤» 

A couple of constructs above have a space after the opening angle bracket. That space isn't accidental. Numerics that are often written using an operator, such as 1/2 (Rat, division operator) and 1+2i (Complex, addition) can be written as a literal that doesn't involve the use of an operator: angle brackets without any spaces between the brackets and the characters inside. By adding spaces within the brackets, we tell the compiler that not only we want a Rat or Complex literal, but we also want it to be an allomorph: the RatStr or ComplexStr, in this case.

If the numeric literal doesn't use any operators, then writing it inside the angle brackets, even without including any spaces within, would produce the allomorph. (Logic: if you didn't want the allomorph, you wouldn't use the angle brackets. The same isn't true for operator-using numbers as some constructs, such as signature literals, do not let you use operators, so you can't just omit angle brackets for such numeric literals).

Available Allomorphs

The core language offers the following allomorphs:

Type Allomorph of Example
IntStr Int and Str <42>
NumStr Num and Str <42e0>
ComplexStr Complex and Str < 1+2i>
RatStr Rat and Str <1.5>

Note: there is no FatRatStr type.

Coercion of Allomorphs

Keep in mind that allomorphs are simply subclasses of the two (or three) types they represent. Just as a variable or parameter type-constrained to Foo can accept any subclass of Foo, so will a variable or parameter type-constrained to Int will accept an IntStr allomorph:

sub foo(Int $x) { say $x.^name } 
 foo <42>;                          # OUTPUT: «IntStr␤» 
 my Num $y = <42e0>; 
 say $y.^name;                      # OUTPUT: «NumStr␤» 

This, of course, also applies to parameter coercers:

sub foo(Int(Cool) $x) { say $x.^name } 
 foo <42>;  # OUTPUT: «IntStr␤» 

The given allomorph is already an object of type Int, so it does not get converted to a "plain" Int in this case.

Of course, the power of allomorphs would be severely diminished if there were no way to "collapse" them to one of their components. Thus, if you explicitly call a method with the name of the type to coerce to, you'll get just that component. The same applies to any proxy methods, such as calling method .Numeric instead of .Int or using the prefix:<~> operator instead of .Str method call.

my $al := IntStr.new: 42, "forty two"; 
 say $al.Str;  # OUTPUT: «forty two␤» 
 say +$al;     # OUTPUT: «42␤» 
 
 say <1/99999999999999999999>.Rat.^name;    # OUTPUT: «Rat␤» 
 say <1/99999999999999999999>.FatRat.^name; # OUTPUT: «FatRat␤» 

A handy way to coerce a whole list of allomorphs is by hypering the appropriate prefix operator:

say map *.^name,   <42 50e0 100>;  # OUTPUT: «(IntStr NumStr IntStr)␤» 
 say map *.^name, +«<42 50e0 100>;  # OUTPUT: «(Int Num Int)␤» 
 say map *.^name, ~«<42 50e0 100>;  # OUTPUT: «(Str Str Str)␤» 

Object Identity

The above discussion on coercing allomorphs becomes more important when we consider object identity. Some constructs utilize it to ascertain whether two objects are "the same". And while to humans an allomorphic 42 and regular 42 might appear "the same", to those constructs, they're entirely different objects:

# "42" shows up twice in the result: 42 and <42> are different objects: 
 say unique 1, 1, 1, 42, <42>; # OUTPUT: «(1 42 42)␤» 
 # Use a different operator to `unique` with: 
 say unique :with(&[==]), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤» 
 # Or coerce the input instead (faster than using a different `unique` operator): 
 say unique :as(*.Int), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤» 
 say unique +«(1, 1, 1, 42, <42>);         # OUTPUT: «(1 42)␤» 
 
 # Parameterized Hash with `Any` keys does not stringify them; our key is of type `Int`: 
 my %h{Any} = 42 => "foo"; 
 # But we use the allomorphic key of type `IntStr`, which is not in the Hash: 
 say %h<42>:exists;           # OUTPUT: «False␤» 
 # Must use curly braces to avoid the allomorph: 
 say %h{42}:exists;           # OUTPUT: «True␤» 
 
 # We are using a set operator to look up an `Int` object in a list of `IntStr` objects: 
 say 42 ∈ <42 100 200>; # OUTPUT: «False␤» 
 # Convert it to an allomorph: 
 say <42> ∈ <42 100 200>; # OUTPUT: «True␤» 
 # Or convert the items in the list to plain `Int` objects: 
 say 42 ∈ +«<42 100 200>; # OUTPUT: «True␤» 

Be mindful of these object identity differences and coerce your allomorphs as needed.

Native Numerics

As the name suggests, native numerics offer access to native numerics—i.e. those offered directly by your hardware. This in turn offers two features: overflow/underflow and better performance.

NOTE: at the time of this writing (2018.05), certain implementations (such as Rakudo) offer somewhat spotty details on native types, such as whether int64 is available and is of 64-bit size on 32-bit machines, and how to detect when your program is running on such hardware.

Available Native Numerics

Native type Base numeric Size
int integer 64-bits
int8 integer 8-bits
int16 integer 16-bits
int32 integer 32-bits
int64 integer 64-bits
uint unsigned integer 64-bits
uint8 unsigned integer 8-bits
uint16 unsigned integer 16-bits
uint32 unsigned integer 32-bits
uint64 unsigned integer 64-bits
num floating point 64-bits
num32 floating point 32-bits
num64 floating point 64-bits
atomicint integer sized to offer CPU-provided atomic operations. (typically 64 bits on 64-bit platforms and 32 bits on 32-bit ones)

Creating Native Numerics

To create a natively-typed variable or parameter, simply use the name of one of the available numerics as the type constraint:

my int32 $x = 42; 
 sub foo(num $y) {} 
 class { has int8 $.z } 

At times, you may wish to coerce some value to a native type without creating any usable variables. There are no .int or similar coercion methods (method calls are latebound, so they're not well-suited for this purpose). Instead, simply use an anonymous variable:

some-native-taking-sub (my int $ = $y), (my int32 $ = $z) 

Overflow/Underflow

Trying to assign a value that does not fit into a particular native type, produces an exception. This includes attempting to give too large an argument to a native parameter:

my int $x = 2¹⁰⁰; 
 # OUTPUT: 
 # Cannot unbox 101 bit wide bigint into native integer 
 #  in block <unit> at -e line 1 
 
 sub f(int $x) { $x }; say f 2⁶⁴ 
 # OUTPUT: 
 # Cannot unbox 65 bit wide bigint into native integer 
 #   in sub f at -e line 1 
 #   in block <unit> at -e line 1 

However, modifying an already-existing value in such a way that it becomes too big/small, produces overflow/underflow behaviour:

my int $x = 2⁶³-1; 
 say $x;             # OUTPUT: «9223372036854775807␤» 
 say ++$x;           # OUTPUT: «-9223372036854775808␤» 
 
 my uint8 $x; 
 say $x;             # OUTPUT: «0␤» 
 say $x -= 100;      # OUTPUT: «156␤» 

Creating objects that utilize native types does not involve direct assignment by the programmer and so these constructs offer overflow/underflow behaviour instead of throwing exceptions.

say Buf.new(1000, 2000, 3000).List; # OUTPUT: «(232 208 184)␤» 
 say my uint8 @a = 1000, 2000, 3000; # OUTPUT: «232 208 184␤» 

Auto-Boxing

While they can be referred to as "native types", native numerics are not actually classes that have any sort of methods available. However, you can call any of the methods available on non-native versions of these numerics. What's going on?

my int8 $x = -42; 
 say $x.abs; # OUTPUT: «42␤» 

This behaviour is known as "auto-boxing". The compiler automatically "boxes" the native type into a full-featured higher-level type with all the methods. In other words, the int8 above was automatically converted to an Int and it's the Int class that then provided the abs method that was called.

This detail is significant when you're using native types for performance gains. If the code you're using results in a lot of auto-boxing being performed you might get worse performance with native types than you would with non-natives:

my $a = -42; 
 my int $a-native = -42; 
 { for ^1000_000 { $a.abs        }; say now - ENTER now } # OUTPUT: «0.38180862␤» 
 { for ^1000_000 { $a-native.abs }; say now - ENTER now } # OUTPUT: «0.938720␤» 

As you can see above, the native variant is more than twice slower. The reason is the method call requires the native type to be boxed, while no such thing is needed in the non-native variant, hence the performance loss.

In this particular case, we can simply switch to a subroutine form of abs, which can work with native types without boxing them. In other cases, you may need to seek out other solutions to avoid excessive autoboxing, including switching to non-native types for a portion of the code.

my $a = -42; 
 my int $a-native = -42; 
 { for ^1000_000 { abs $a        }; say now - ENTER now } # OUTPUT: «0.38229177␤» 
 { for ^1000_000 { abs $a-native }; say now - ENTER now } # OUTPUT: «0.3088305␤» 

Default Values

Since there are no classes behind native types, there are no type objects you'd normally get with variables that haven't been initialized. Thus, native types are automatically initialized to zero. In 6.c language, native floating point types (num, num32, and num64) are initialized to value NaN; it is proposed to become 0e0 by default in 6.d language.

Native Dispatch

It is possible to have native candidates alongside non-native candidates to, for example, offer faster algorithms with native candidates when sizes are predictable, but to fallback to slower non-native alternatives otherwise. The following are the rules concerning multi-dispatch involving native candidates.

First, the size of the native type does not play a role in dispatch and an int8 is considered to be the same as int16 or int:

multi foo(int   $x) { say "int" } 
 multi foo(int32 $x) { say "int32" } 
 foo my int $x = 42; 
 # OUTPUT: 
 # Ambiguous call to 'foo(Int)'; these signatures all match: 
 # :(int $x) 
 # :(int32 $x) 

Second, if a routine is an only—i.e. it is not a multi—that takes a non-native type but a native one was given during the call, or vice-versa, then the argument will be auto-boxed or auto-unboxed to make the call possible. If the given argument is too large to fit into the native parameter, an exception will be thrown:

-> int {}( 42 );            # OK; auto-unboxing 
 -> int {}( 2¹⁰⁰ );          # Too large; exception 
 -> Int {}( 2¹⁰⁰ );          # OK; non-native parameter 
 -> Int {}( my int $ = 42 ); # OK; auto-boxing 

When it comes to multi routines, native arguments will always be auto-boxed if no native candidates are available to take them:

multi foo (Int $x) { $x } 
 say foo my int $ = 42; # OUTPUT: «42␤» 

The same luxury is not afforded when going the other way. If only a native candidate is available, a non-native argument will not be auto-unboxed and instead an exception indicating no candidates matched will be thrown (the reason for this asymmetry is a native type can always be boxed, but a non-native may be too large to fit into a native):

multi f(int $x) { $x } 
 my $x = 2; 
 say f $x; 
 # OUTPUT: 
 # Cannot resolve caller f(Int); none of these signatures match: 
 #     (int $x) 
 #   in block <unit> at -e line 1 

However, this rule is waived if a call is being made where one of the arguments is a native type and another one is a numeric literal:

multi f(int, int) {} 
 f 42, my int $x; # Successful call 

This way you do not have to constantly write, for example, $n +> 2 as $n +> (my int $ = 2). The compiler knows the literal is small enough to fit to a native type and converts it to a native.

Atomic Operations

The language offers some operations that are guaranteed to be performed atomically, i.e. safe to be executed by multiple threads without the need for locking with no risk of data races.

For such operations, the atomicint native type is required. This type is similar to a plain native int, except it is sized such that CPU-provided atomic operations can be performed upon it. On a 32-bit CPU it will typically be 32 bits in size, and on an a 64-bit CPU it will typically be 64 bits in size.

# !!WRONG!! Might be non-atomic on some systems 
 my int $x; 
 await ^100 .map: { start $x⚛++ }; 
 say $x; # OUTPUT: «98␤» 
 
 # RIGHT! The use of `atomicint` type guarantees operation is atomic 
 my atomicint $x; 
 await ^100 .map: { start $x⚛++ }; 
 say $x; # OUTPUT: «100␤» 

The similarity to int is present in multi dispatch as well: an atomicint, plain int, and the sized int variants are all considered to be the same by the dispatcher and cannot be differentiated through multi-dispatch.

Numeric Infectiousness

Numeric "infectiousness" dictates the resultant type when two numerics of different types are involved in some mathematical operations. A type is said to be more infectious than the other type if the result is of that type rather than the type of the other operand. For example, Num type is more infectious than an Int, thus we can expect 42e0 + 42 to produce a Num as the result.

The infectiousness is as follows, with the most infectious type listed first:

say (2 + 2e0).^name; # Int + Num => OUTPUT: «Num␤» 
 say (½ + ½).^name; # Rat + Rat => OUTPUT: «Rat␤» 
 say (FatRat.new(1,2) + ½).^name; # FatRat + Rat => OUTPUT: «FatRat␤» 

The allomorphs have the same infectiousness as their numeric component. Native types get autoboxed and have the same infectiousness as their boxed variant.

41 Object orientation

Object orientation in Perl 6

Perl 6 provides strong support for Object Oriented Programming (OOP). Although Perl 6 allows programmers to program in multiple paradigms, Object Oriented Programming is at the heart of the language.

Perl 6 comes with a wealth of predefined types, which can be classified in two categories: normal and native types. Everything that you can store in a variable is either a native value or an object. That includes literals, types (type objects), code and containers.

Native types are used for low-level types (like uint64). Even if native types do not have the same capabilities as objects, if you call methods on them, they are automatically boxed into normal objects.

Everything that is not a native value is an <object>. Objects do allow for both inheritance and encapsulation.

Using Objects

To call a method on an object, add a dot, followed by the method name:

say "abc".uc; 
 # OUTPUT: «ABC␤» 

This calls the uc method on "abc", which is an object of type Str. To supply arguments to the method, add arguments inside parentheses after the method.

my $formatted-text = "Fourscore and seven years ago...".indent(8); 
 say $formatted-text; 
 # OUTPUT: «        Fourscore and seven years ago...␤» 

$formatted-text now contains the above text, but indented 8 spaces.

Multiple arguments are separated by commas:

my @words = "Abe", "Lincoln"; 
 @words.push("said", $formatted-text.comb(/\w+/)); 
 say @words; 
 # OUTPUT: «[Abe Lincoln said (Fourscore and seven years ago)]␤» 

Multiple arguments can be specified by separating the argument list with a colon:

say @words.join: '--'; 
 # OUTPUT: «Abe--Lincoln--said--Fourscore--and--seven--years--ago␤» 

Since you have to put a : after the method if you want to pass arguments without parentheses, a method call without a colon or parentheses is unambiguously a method call without an argument list:

say 4.log:   ; # OUTPUT: «1.38629436111989␤» ( natural logarithm of 4 )
say 4.log: +2; # OUTPUT: «2␤» ( base-2 logarithm of 4 )
say 4.log  +2; # OUTPUT: «3.38629436111989␤» ( natural logarithm of 4, plus 2 )

Many operations that don't look like method calls (for example, smartmatching or interpolating an object into a string) result in method calls under the hood.

Methods can return mutable containers, in which case you can assign to the return value of a method call. This is how read-writable attributes to objects are used:

$*IN.nl-in = "\r\n"; 

Here, we call method nl-in on the $*IN object, without arguments, and assign to the container it returned with the = operator.

All objects support methods from class Mu, which is the type hierarchy root. All objects derive from Mu.

Type Objects

Types themselves are objects and you can get the type object by writing its name:

my $int-type-obj = Int; 

You can ask any object for its type object by calling the WHAT method (which is actually a macro in method form):

my $int-type-obj = 1.WHAT; 

Type objects (other than Mu) can be compared for equality with the === identity operator:

sub f(Int $x) { 
     if $x.WHAT === Int { 
         say 'you passed an Int'; 
     } 
     else { 
         say 'you passed a subtype of Int'; 
     } 
 } 

Although, in most cases, the .isa method will suffice:

sub f($x) { 
     if $x.isa(Int) { 
         ... 
     } 
     ... 
 } 

Subtype checking is done by smartmatching:

if $type ~~ Real { 
     say '$type contains Real or a subtype thereof'; 
 } 

Classes

Classes are declared using the class keyword, typically followed by a name.

class Journey { }

This declaration results in a type object being created and installed in the current package and current lexical scope under the name Journey. You can also declare classes lexically:

my class Journey { }

This restricts their visibility to the current lexical scope, which can be useful if the class is an implementation detail nested inside a module or another class.

Attributes

Attributes are variables that exist per instance of a class; when instantiated to a value, the association between the variable and its value is called a property. They are where the state of an object is stored. In Perl 6, all attributes are private, that means they can be accessed directly only by the class instance itself. They are typically declared using the has declarator and the ! twigil.

class Journey {
    has $!origin;
    has $!destination;
    has @!travelers;
    has $!notes;
}

While there is no such thing as a public (or even protected) attribute, there is a way to have accessor methods generated automatically: replace the ! twigil with the . twigil (the . should remind you of a method call).

class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes;
}

This defaults to providing a read-only accessor. In order to allow changes to the attribute, add the is rw trait:

class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes is rw;
}

Now, after a Journey object is created, its .origin, .destination, and .notes will all be accessible from outside the class, but only .notes can be modified.

If an object is instantiated without certain attributes, such as origin or destination, we may not get the desired result. To prevent this, provide default values or make sure that an attribute is set on object creation by marking an attribute with an is required trait.

class Journey {
    # error if origin is not provided
    has $.origin is required;
    # set the destination to Orlando as default (unless that is the origin!)
    has $.destination = self.origin eq 'Orlando' ?? 'Kampala' !! 'Orlando';
    has @!travelers;
    has $.notes is rw;
}

Since classes inherit a default constructor from Mu and we have requested that some accessor methods are generated for us, our class is already somewhat functional.

# Create a new instance of the class. 
 my $vacation = Journey.new( 
     origin      => 'Sweden', 
     destination => 'Switzerland', 
     notes       => 'Pack hiking gear!' 
 ); 
 
 # Use an accessor; this outputs Sweden. 
 say $vacation.origin; 
 
 # Use an rw accessor to change the value. 
 $vacation.notes = 'Pack hiking gear and sunglasses!'; 

Note that, although the default constructor can initialize read-only attributes, it will only set attributes that have an accessor method. That is, even if you pass travelers => ["Alex", "Betty"] to the default constructor, the attribute @!travelers is not initialized.

Methods

Methods are declared with the method keyword inside a class body.

class Journey { 
     has $.origin; 
     has $.destination; 
     has @!travelers; 
     has $.notes is rw; 
 
     method add-traveler($name) { 
         if $name ne any(@!travelers) { 
             push @!travelers, $name; 
         } 
         else { 
             warn "$name is already going on the journey!"; 
         } 
     } 
 
     method describe() { 
         "From $!origin to $!destination" 
     } 
 } 

A method can have a signature, just like a subroutine. Attributes can be used in methods and can always be used with the ! twigil, even if they are declared with the . twigil. This is because the . twigil declares a ! twigil and generates an accessor method.

Looking at the code above, there is a subtle but important difference between using $!origin and $.origin in the method describe. $!origin is an inexpensive and obvious lookup of the attribute. $.origin is a method call and thus may be overridden in a subclass. Only use $.origin if you want to allow overriding.

Unlike subroutines, additional named arguments will not produce compile time or runtime errors. That allows chaining of methods via Re-dispatching.

You may write your own accessors to override any or all of the autogenerated ones.

my $ⲧ = " " xx 4;
class Journey {
    has $.origin;
    has $.destination;
    has @.travelers;
    has Str $.notes is rw;

    multi method notes() { "$!notes\n" };
    multi method notes( Str $note ) { $!notes ~= "$note\n$ⲧ" };

    method Str { "⤷ $!origin\n$ⲧ" ~ self.notes() ~ "$!destination ⤶\n" };
}

my $trip = Journey.new( :origin<Here>, :destination<There>,
                        travelers => <þor Freya> );

$trip.notes("First steps");
notes $trip: "Almost there";
print $trip;

# OUTPUT:
#⤷ Here
#       First steps
#       Almost there
#
#There ⤶

The declared multi method notes overrides the auto-generated methods implicit in the declaration of $.notes, using a different signature for reading and writing.

Please note that in notes $trip: "Almost there" we are using indirect invocant syntax, which puts first the method name, then the object, and then, separated by a colon, the arguments: method invocant: arguments. We can use this syntax whenever it feels more natural than the classical period-and-parentheses one. It works exactly in the same way.

Method names can be resolved at runtime with the ."" operator.

class A { has $.b };
my $name = 'b';
A.new."$name"().say;
# OUTPUT: «(Any)␤»

The syntax used to update $.notes changed in this section with respect to the previous #Attributes section. Instead of an assignment:

    $vacation.notes = 'Pack hiking gear and sunglasses!'; 

we now do a method call:

    $trip.notes("First steps"); 

Overriding the default auto-generated accessor means it is no longer available to provide a mutable container on return for an assignment. A method call is the preferred approach to adding computation and logic to the update of an attribute. Many modern languages can update an attribute by overloading assignment with a “setter” method. While Perl 6 can overload the assignment operator for this purpose with a Proxy object, overloading assignment to set attributes with complex logic is currently discouraged as weaker object oriented design.

Class and Instance Methods

A method's signature can have an invocant as its first parameter followed by a colon, which allows for the method to refer to the object it was called on.

class Foo {
    method greet($me: $person) {
        say "Hi, I am $me.^name(), nice to meet you, $person";
    }
}
Foo.new.greet("Bob");    # OUTPUT: «Hi, I am Foo, nice to meet you, Bob␤»

Providing an invocant in the method signature also allows for defining the method as either as a class method, or as an object method, through the use of type constraints. The ::?CLASS variable can be used to provide the class name at compile time, combined with either :U (for class methods) or :D (for instance methods).

class Pizza {
    has $!radius = 42;
    has @.ingredients;

    # class method: construct from a list of ingredients
    method from-ingredients(::?CLASS:U $pizza: @ingredients) {
        $pizza.new( ingredients => @ingredients );
    }

    # instance method
    method get-radius(::?CLASS:D:) { $!radius }
}
my $p = Pizza.from-ingredients: <cheese pepperoni vegetables>;
say $p.ingredients;     # OUTPUT: «[cheese pepperoni vegetables]␤»
say $p.get-radius;      # OUTPUT: «42␤»
say Pizza.get-radius;   # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'get-radius' must be
#          an object instance of type 'Pizza',
#          not a type object of type 'Pizza'.
#          Did you forget a '.new'?»

A method can be both a class and object method by using the multi declarator:

class C {
    multi method f(::?CLASS:U:) { say "class method"  }
    multi method f(::?CLASS:D:) { say "object method" }
}
C.f;       # OUTPUT: «class method␤»
C.new.f;   # OUTPUT: «object method␤»

self

Inside a method, the term self is available, which is bound to the invocant. self can be used to call further methods on the invocant, including constructors:

class Box {
  has $.data;

  method make-new-box-from() {
      self.new: data => $!data;
  }
}

self can be used in class or instance methods as well, though beware of trying to invoke one type of method from the other:

class C {
    method g()            { 42     }
    method f(::?CLASS:U:) { self.g }
    method d(::?CLASS:D:) { self.f }
}
C.f;        # OUTPUT: «42␤»
C.new.d;    # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'f' must be a type object of type 'C',
#          not an object instance of type 'C'.  Did you forget a 'multi'?»

Within methods, $.origin works the same as self.origin, however the colon-syntax for method arguments is only supported for method calls using self, not the shortcut.

Note that if the relevant methods bless, CREATE of Mu are not overloaded, self will point to the type object in those methods.

On the other hand, BUILDALL and the submethods BUILD and TWEAK are called on instances, in different stages of initialization. In the latter two submethods, submethods of the same name from subclasses have not yet run, so you should not rely on potentially virtual method calls inside these methods.

Private Methods

Methods with an exclamation mark ! before the method name are not callable from anywhere outside the defining class; such methods are private in the sense that they are not visible from outside the class that declares them. Private methods are invoked with an exclamation mark instead of a dot:

method !do-something-private($x) {
    ...
}
method public($x) {
    if self.precondition {
        self!do-something-private(2 * $x)
    }
}

Private methods are not inherited by subclasses.

Submethods

Submethods are public methods that are not inherited by subclasses. The name stems from the fact that they are semantically similar to subroutines.

Submethods are useful for object construction and destruction tasks, as well as for tasks that are so specific to a certain type that subtypes must certainly override them.

For example, the default method new calls submethod BUILD on each class in an inheritance chain:

class Point2D { 
     has $.x; 
     has $.y; 
 
     submethod BUILD(:$!x, :$!y) { 
         say "Initializing Point2D"; 
     } 
 } 
 
 class InvertiblePoint2D is Point2D { 
     submethod BUILD() { 
         say "Initializing InvertiblePoint2D"; 
     } 
     method invert { 
         self.new(x => - $.x, y => - $.y); 
     } 
 } 
 
 say InvertiblePoint2D.new(x => 1, y => 2); 
 # OUTPUT: «Initializing Point2D␤» 
 # OUTPUT: «Initializing InvertiblePoint2D␤» 
 # OUTPUT: «InvertiblePoint2D.new(x => 1, y => 2)␤» 

See also: #Object Construction.

Inheritance

Classes can have parent classes.

class Child is Parent1 is Parent2 { } 

If a method is called on the child class, and the child class does not provide that method, the method of that name in one of the parent classes is invoked instead, if it exists. The order in which parent classes are consulted is called the method resolution order (MRO). Perl 6 uses the C3 method resolution order. You can ask a type for its MRO through a call to its meta class:

say List.^mro;      # ((List) (Cool) (Any) (Mu))

If a class does not specify a parent class, Any is assumed by default. All classes directly or indirectly derive from Mu, the root of the type hierarchy.

All calls to public methods are "virtual" in the C++ sense, which means that the actual type of an object determines which method to call, not the declared type:

class Parent { 
     method frob { 
         say "the parent class frobs" 
     } 
 } 
 
 class Child is Parent { 
     method frob { 
         say "the child's somewhat more fancy frob is called" 
     } 
 } 
 
 my Parent $test; 
 $test = Child.new; 
 $test.frob;          # calls the frob method of Child rather than Parent 
 # OUTPUT: «the child's somewhat more fancy frob is called␤» 

Object Construction

Objects are generally created through method calls, either on the type object or on another object of the same type.

Class Mu provides a constructor method called new, which takes named arguments and uses them to initialize public attributes.

class Point {
    has $.x;
    has $.y;
}
my $p = Point.new( x => 5, y => 2);
#             ^^^ inherited from class Mu
say "x: ", $p.x;
say "y: ", $p.y;
# OUTPUT: «x: 5␤»
# OUTPUT: «y: 2␤»

Mu.new calls method bless on its invocant, passing all the named arguments. bless creates the new object and then calls method BUILDALL on it. BUILDALL walks all subclasses in reverse method resolution order (i.e. from Mu to most derived classes) and in each class checks for the existence of a method named BUILD. If the method exists, the method is called with all the named arguments from the new method. If not, the public attributes from this class are initialized from named arguments of the same name. In either case, if neither BUILD nor the default mechanism has initialized the attribute, default values are applied.

After the BUILD methods have been called, methods named TWEAK are called, if they exist, again with all the named arguments that were passed to new. See an example of its use below.

Due to the default behavior of BUILDALL and BUILD submethods, named arguments to the constructor new derived from Mu can correspond directly to public attributes of any of the classes in the method resolution order, or to any named parameter of any BUILD submethod.

This object construction scheme has several implications for customized constructors. First, custom BUILD methods should always be submethods, otherwise they break attribute initialization in subclasses. Second, BUILD submethods can be used to run custom code at object construction time. They can also be used for creating aliases for attribute initialization:

class EncodedBuffer { 
     has $.enc; 
     has $.data; 
 
     submethod BUILD(:encoding(:$enc), :$data) { 
         $!enc  :=  $enc; 
         $!data := $data; 
     } 
 } 
 my $b1 = EncodedBuffer.new( encoding => 'UTF-8', data => [64, 65] ); 
 my $b2 = EncodedBuffer.new( enc      => 'UTF-8', data => [64, 65] ); 
 #  both enc and encoding are allowed now 

Since passing arguments to a routine binds the arguments to the parameters, a separate binding step is unnecessary if the attribute is used as a parameter. Hence the example above could also have been written as:

submethod BUILD(:encoding(:$!enc), :$!data) { 
     # nothing to do here anymore, the signature binding 
     # does all the work for us. 
 } 

However, be careful when using this auto-binding of attributes when the attribute may have special type requirements, such as an :$!id that must be a positive integer. Remember, default values will be assigned unless you specifically take care of this attribute, and that default value will be Any, which would cause a type error.

The third implication is that if you want a constructor that accepts positional arguments, you must write your own new method:

class Point {
    has $.x;
    has $.y;
    method new($x, $y) {
        self.bless(:$x, :$y);
    }
}

However this is considered poor practice, because it makes correct initialization of objects from subclasses harder.

Another thing to note is that the name new is not special in Perl 6. It is merely a common convention. You can call bless from any method at all, or use CREATE to fiddle around with low-level workings.

Another pattern of hooking into object construction is by writing your own method BUILDALL. To make sure that initialization of superclasses works fine, you need to callsame to invoke the parent classes BUILDALL.

class MyClass { 
     method BUILDALL(|) { 
         # initial things here 
 
         callsame;   # call the parent classes (or default) BUILDALL 
 
         # you can do final checks here. 
 
         self # return the fully built object 
     } 
 } 

The TWEAK submethod allows you to check things or modify attributes after object construction:

class RectangleWithCachedArea { 
     has ($.x1, $.x2, $.y1, $.y2); 
     has $.area; 
     submethod TWEAK() { 
         $!area = abs( ($!x2 - $!x1) * ( $!y2 - $!y1) ); 
     } 
 } 
 
 say RectangleWithCachedArea.new( x2 => 5, x1 => 1, y2 => 1, y1 => 0).area; 
 # OUTPUT: «4␤» 

Object Cloning

The cloning is done using clone method available on all objects, which shallow-clones both public and private attributes. New values for public attributes can be supplied as named arguments.

class Foo { 
     has $.foo = 42; 
     has $.bar = 100; 
 } 
 
 my $o1 = Foo.new; 
 my $o2 = $o1.clone: :bar(5000); 
 say $o1; # Foo.new(foo => 42, bar => 100) 
 say $o2; # Foo.new(foo => 42, bar => 5000) 

See document for clone for details on how non-scalar attributes get cloned, as well as examples of implementing your own custom clone methods.

Roles

Roles are in some ways similar to classes, in that they are a collection of attributes and methods. They differ in that roles are also meant for describing only parts of an object's behavior and in how roles are applied to classes. Or to phrase it differently, classes are meant for managing objects and roles are meant for managing behavior and code reuse.

use MONKEY-SEE-NO-EVAL; 
 role Serializable { 
     method serialize() { 
         self.perl; # very primitive serialization 
     } 
     method deserialize($buf) { 
         EVAL $buf; # reverse operation to .perl 
     } 
 } 
 
 class Point does Serializable { 
     has $.x; 
     has $.y; 
 } 
 my $p = Point.new(:x(1), :y(2)); 
 my $serialized = $p.serialize; 
 my $clone-of-p = Point.deserialize($serialized); 
 say $clone-of-p.x; # OUTPUT: «1␤» 

Roles are immutable as soon as the compiler parses the closing curly brace of the role declaration.

Application of Role

Role application differs significantly from class inheritance. When a role is applied to a class, the methods of that role are copied into the class. If multiple roles are applied to the same class, conflicts (e.g. attributes or non-multi methods of the same name) cause a compile-time error, which can be solved by providing a method of the same name in the class.

This is much safer than multiple inheritance, where conflicts are never detected by the compiler, but are instead resolved to the superclass that appears earlier in the method resolution order, which might not be what the programmer wanted.

For example, if you've discovered an efficient method to ride cows, and are trying to market it as a new form of popular transportation, you might have a class Bull, for all the bulls you keep around the house, and a class Automobile, for things that you can drive.

class Bull {
    has Bool $.castrated = False;
    method steer {
        # Turn your bull into a steer
        $!castrated = True;
        return self;
    }
}
class Automobile {
    has $.direction;
    method steer($!direction) { }
}
class Taurus is Bull is Automobile { }

my $t = Taurus.new;
say $t.steer;
# OUTPUT: «Taurus.new(castrated => Bool::True, direction => Any)␤»

With this setup, your poor customers will find themselves unable to turn their Taurus and you won't be able to make more of your product! In this case, it may have been better to use roles:

role Bull-Like { 
     has Bool $.castrated = False; 
     method steer { 
         # Turn your bull into a steer 
         $!castrated = True; 
         return self; 
     } 
 } 
 role Steerable { 
     has Real $.direction; 
     method steer(Real $d = 0) { 
         $!direction += $d; 
     } 
 } 
 class Taurus does Bull-Like does Steerable { } 

This code will die with something like:

===SORRY!=== 
 Method 'steer' must be resolved by class Taurus because it exists in 
 multiple roles (Steerable, Bull-Like) 

This check will save you a lot of headaches:

class Taurus does Bull-Like does Steerable { 
     method steer($direction?) { 
         self.Steerable::steer($direction) 
     } 
 } 

When a role is applied to a second role, the actual application is delayed until the second role is applied to a class, at which point both roles are applied to the class. Thus

role R1 {
    # methods here
}
role R2 does R1 {
    # methods here
}
class C does R2 { }

produces the same class C as

role R1 {
    # methods here
}
role R2 {
    # methods here
}
class C does R1 does R2 { }

Stubs

When a role contains a stubbed method, a non-stubbed version of a method of the same name must be supplied at the time the role is applied to a class. This allows you to create roles that act as abstract interfaces.

role AbstractSerializable { 
     method serialize() { ... }        # literal ... here marks the 
                                       # method as a stub 
 } 
 
 # the following is a compile time error, for example 
 #        Method 'serialize' must be implemented by Point because 
 #        it's required by a role 
 
 class APoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
 } 
 
 # this works: 
 class SPoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
     method serialize() { "p($.x, $.y)" } 
 } 

The implementation of the stubbed method may also be provided by another role.

Inheritance

Roles cannot inherit from classes, but they may carry classes, causing any class which does that role to inherit from the carried classes. So if you write:

role A is Exception { } 
 class X::Ouch does A { } 
 X::Ouch.^parents.say # OUTPUT: «((Exception))␤» 

then X::Ouch will inherit directly from Exception, as we can see above by listing its parents.

As they do not use what can properly be called inheritance, roles are not part of the class hierarchy. Roles are listed with the .^roles meta-method instead, which uses transitive as flag for including all levels or just the first one. Despite this, a class or instance may still be tested with smartmatches or type constraints to see if it does a role.

role F { } 
 class G does F { } 
 G.^roles.say;                    # OUTPUT: «((F))␤» 
 role Ur {} 
 role Ar does Ur {} 
 class Whim does Ar {}; Whim.^roles(:!transitive).say;   # OUTPUT: «((Ar))␤» 
 say G ~~ F;                      # OUTPUT: «True␤» 
 multi a (F $a) { "F".say } 
 multi a ($a)   { "not F".say } 
 a(G);                            # OUTPUT: «F␤» 

Pecking order

A method defined directly in a class will always override definitions from applied roles or from inherited classes. If no such definition exists, methods from roles override methods inherited from classes. This happens both when said class was brought in by a role, and also when said class was inherited directly.

role M {
  method f { say "I am in role M" }
}

class A {
  method f { say "I am in class A" }
}

class B is A does M {
  method f { say "I am in class B" }
}

class C is A does M { }

B.new.f; # OUTPUT «I am in class B␤»
C.new.f; # OUTPUT «I am in role M␤»

Note that each candidate for a multi-method is its own method. In this case, the above only applies if two such candidates have the same signature. Otherwise, there is no conflict, and the candidate is just added to the multi-method.

Automatic Role Punning

Any attempt to directly instantiate a role or use it as a type object will automatically create a class with the same name as the role, making it possible to transparently use a role as if it were a class.

role Point { 
     has $.x; 
     has $.y; 
     method abs { sqrt($.x * $.x + $.y * $.y) } 
     method dimensions { 2 } 
 } 
 say Point.new(x => 6, y => 8).abs; # OUTPUT «10␤» 
 say Point.dimensions;              # OUTPUT «2␤» 

We call this automatic creation of classes punning, and the generated class a pun.

Punning is not caused by most meta-programming constructs, however, as those are sometimes used to work directly with roles.

Parameterized Roles

Roles can be parameterized, by giving them a signature in square brackets:

role BinaryTree[::Type] { 
     has BinaryTree[Type] $.left; 
     has BinaryTree[Type] $.right; 
     has Type $.node; 
 
     method visit-preorder(&cb) { 
         cb $.node; 
         for $.left, $.right -> $branch { 
             $branch.visit-preorder(&cb) if defined $branch; 
         } 
     } 
     method visit-postorder(&cb) { 
         for $.left, $.right -> $branch { 
             $branch.visit-postorder(&cb) if defined $branch; 
         } 
         cb $.node; 
     } 
     method new-from-list(::?CLASS:U: *@el) { 
         my $middle-index = @el.elems div 2; 
         my @left         = @el[0 .. $middle-index - 1]; 
         my $middle       = @el[$middle-index]; 
         my @right        = @el[$middle-index + 1 .. *]; 
         self.new( 
             node    => $middle, 
             left    => @left  ?? self.new-from-list(@left)  !! self, 
             right   => @right ?? self.new-from-list(@right) !! self, 
         ); 
     } 
 } 
 
 my $t = BinaryTree[Int].new-from-list(4, 5, 6); 
 $t.visit-preorder(&say);    # OUTPUT: «5␤4␤6␤» 
 $t.visit-postorder(&say);   # OUTPUT: «4␤6␤5␤» 

Here the signature consists only of a type capture, but any signature will do:

enum Severity <debug info warn error critical>; 
 
 role Logging[$filehandle = $*ERR] { 
     method log(Severity $sev, $message) { 
         $filehandle.print("[{uc $sev}] $message\n"); 
     } 
 } 
 
 Logging[$*OUT].log(debug, 'here we go'); # OUTPUT: «[DEBUG] here we go␤» 

You can have multiple roles of the same name, but with different signatures; the normal rules of multi dispatch apply for choosing multi candidates.

Mixins of Roles

Roles can be mixed into objects. A role's given attributes and methods will be added to the methods and attributes the object already has. Multiple mixins and anonymous roles are supported.

role R { method Str() {'hidden!'} };
my $i = 2 but R;
sub f(\bound){ put bound };
f($i); # OUTPUT: «hidden!␤»
my @positional := <a b> but R;
say @positional.^name; # OUTPUT: «List+{R}␤»

Note that the object got the role mixed in, not the object's class or the container. Thus, @-sigiled containers will require binding to make the role stick as is shown in the example with @positional. Some operators will return a new value, which effectively strips the mixin from the result. That is why it might be more clear to mix in the role in the declaration of the variable using does:

role R {};
my @positional does R = <a b>;
say @positional.^name; # OUTPUT: «Array+{R}␤»

The operator infix:<but> is narrower than the list constructor. When providing a list of roles to mix in, always use parentheses.

role R1 { method m {} } 
 role R2 { method n {} } 
 my $a = 1 but R1,R2; # R2 is in sink context, issues a WARNING 
 say $a.^name; 
 # OUTPUT: «Int+{R1}␤» 
 my $all-roles = 1 but (R1,R2); 
 say $all-roles.^name; # OUTPUT: «Int+{R1,R2}␤» 

Mixins can be used at any point in your object's life.

# A counter for Table of Contents
role TOC-Counter {
    has Int @!counters is default(0);
    method Str() { @!counters.join: '.' }
    method inc($level) {
        @!counters[$level - 1]++;
        @!counters.splice($level);
        self
    }
}

my Num $toc-counter = NaN;     # don't do math with Not A Number
say $toc-counter;              # OUTPUT: «NaN␤»
$toc-counter does TOC-Counter; # now we mix the role in
$toc-counter.inc(1).inc(2).inc(2).inc(1).inc(2).inc(2).inc(3).inc(3);
put $toc-counter / 1;          # OUTPUT: «NaN␤» (because that's numerical context)
put $toc-counter;              # OUTPUT: «2.2.2␤» (put will call TOC-Counter::Str)

Roles can be anonymous.

my %seen of Int is default(0 but role :: { method Str() {'NULL'} });
say %seen<not-there>;          # OUTPUT: «NULL␤»
say %seen<not-there>.defined;  # OUTPUT: «True␤» (0 may be False but is well defined)
say Int.new(%seen<not-there>); # OUTPUT: «0␤»

Meta-Object Programming and Introspection

Perl 6 has a meta object system, which means that the behavior of objects, classes, roles, grammars, enums, etc. are themselves controlled by other objects; those objects are called meta objects. Meta objects are, like ordinary objects, instances of classes, in this case we call them meta classes.

For each object or class you can get the meta object by calling .HOW on it. Note that although this looks like a method call, it works more like a macro.

So, what can you do with the meta object? For one you can check if two objects have the same meta class by comparing them for equality:

say 1.HOW ===   2.HOW;      # OUTPUT: «True␤»
say 1.HOW === Int.HOW;      # OUTPUT: «True␤»
say 1.HOW === Num.HOW;      # OUTPUT: «False␤»

Perl 6 uses the word HOW, Higher Order Workings, to refer to the meta object system. Thus it should be no surprise that in Rakudo, the class name of the meta class that controls class behavior is called Perl6::Metamodel::ClassHOW. For each class there is one instance of Perl6::Metamodel::ClassHOW.

But of course the meta model does much more for you. For example, it allows you to introspect objects and classes. The calling convention for methods on meta objects is to call the method on the meta object and pass in the object of interest as first argument to the object. So to get the name of the class of an object, you could write:

my $object = 1;
my $metaobject = 1.HOW;
say $metaobject.name($object);      # OUTPUT: «Int␤»

# or shorter:
say 1.HOW.name(1);                  # OUTPUT: «Int␤»

(The motivation is that Perl 6 also wants to allow a more prototype-based object system, where it's not necessary to create a new meta object for every type).

There's a shortcut to keep from using the same object twice:

say 1.^name;                        # OUTPUT: «Int␤»
# same as
say 1.HOW.name(1);                  # OUTPUT: «Int␤»

See Metamodel::ClassHOW for documentation on the meta class of class and also the general documentation on the meta object protocol.

42 Operators

Common Perl 6 infixes, prefixes, postfixes, and more!

See Sub on how to define operators.

Operator precedence

In an expression like 1 + 2 * 3, the 2 * 3 is evaluated first because the infix * has tighter precedence than the +.

The following table summarizes the precedence levels in Perl 6, from tightest to loosest:

A Level Examples
N Terms 42 3.14 "eek" qq["foo"] $x :!verbose @$array
L Method postfix .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ .:
N Autoincrement ++ --
R Exponentiation **
L Symbolic unary ! + - ~ ? | || +^ ~^ ?^ ^
L Dotty infix .= .
L Multiplicative * × / ÷ % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm
L Additive + - − +| +^ ~| ~^ ?| ?^
L Replication x xx
X Concatenation ~ o ∘
X Junctive and & (&) (.) ∩ ⊍
X Junctive or | ^ (|) (^) (+) (-) ∪ ⊖ ⊎ ∖
L Named unary temp let
N Structural infix but does <=> leg unicmp cmp coll .. ..^ ^.. ^..^
C Chaining infix != ≠ == < <= ≤ > >= ≥ eq ne lt le gt ge ~~ === eqv !eqv =~= ≅ (elem) (cont) (<) (>) (<=) (>=) (<+) (>+) ∈ ∉ ∋ ∌ ⊂ ⊄ ⊃ ⊅ ⊆ ⊈ ⊇ ⊉ ≼ ≽
X Tight and &&
X Tight or || ^^ // min max
R Conditional ?? !! ff ff^ ^ff ^ff^ fff fff^ ^fff ^fff^
R Item assignment = => += -= **= xx=
L Loose unary so not
X Comma operator , :
X List infix Z minmax X X~ X* Xeqv ... … ...^ …^
R List prefix print push say die map substr ... [+] [*] any Z=
X Loose and and andthen notandthen
X Loose or or xor orelse
X Sequencer <==, ==>, <<==, ==>>
N Terminator ; {...}, unless, extra ), ], }

Using two ! symbols below generically to represent any pair of operators that have the same precedence, the associativities specified above for binary operators are interpreted as follows:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
N non ILLEGAL
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

For unary operators this is interpreted as:

A Assoc Meaning of !$a!
L left (!$a)!
R right !($a!)
N non ILLEGAL

In the operator descriptions below, a default associativity of left is assumed.

Operator classification

Operators can occur in several positions relative to a term:

+term prefix
term1 + term2 infix
term++ postfix
(term) circumfix
term1[term2] postcircumfix

Each operator is also available as a subroutine. The name of the routine is formed from the operator category, followed by a colon, then a list quote construct with the symbol(s) that make up the operator:

infix:<+>(1, 2);                # same as 1 + 2
circumfix:«[ ]»(<a b c>);       # same as [<a b c>]

As a special case, a listop (list operator) can stand either as a term or as a prefix. Subroutine calls are the most common listops. Other cases include meta-reduced infix operators ([+] 1, 2, 3) and the #prefix ... etc. stub operators.

Defining custom operators is covered in Defining operators functions.

Metaoperators

Metaoperators can be parameterized with other operators or subroutines in the same way as functions can take functions as parameters. To use a subroutine as a parameter, prefix its name with a &. Perl 6 will generate the actual combined operator in the background, allowing the mechanism to be applied to user defined operators. To disambiguate chained metaoperators, enclose the inner operator in square brackets. There are quite a few metaoperators with different semantics as explained, next.

Substitution operators

Each substitution operator comes into two main forms: a lowercase one (e.g., s///) that performs in-place (i.e., destructive behaviour; and an uppercase form (e.g., S///) that provides a non-destructive behavior.

s/// in-place substitution

my $str = 'old string';
$str ~~ s/o .+ d/new/;
say $str; # OUTPUT: «new string␤»

s/// operates on the $_ topical variable, changing it in place. It uses the given Regex to find portions to replace and changes them to the provided replacement string. Sets $/ to the Match object or, if multiple matches were made, a List of Match objects. Returns $/.

It's common to use this operator with the ~~ smartmatch operator, as it aliases left-hand side to $_, which s/// uses.

Regex captures can be referenced in the replacement part; it takes the same adverbs as the .subst method, which go between the s and the opening /, separated with optional whitespace:

my $str = 'foo muCKed into the lEn';

# replace second 'o' with 'x'
$str ~~ s:2nd/o/x/;

# replace 'M' or 'L' followed by non-whitespace stuff with 'd'
# and lower-cased version of that stuff:
$str ~~ s :g :i/<[ML]> (\S+)/d{lc $0}/;

say $str; # OUTPUT: «fox ducked into the den␤»

You can also use a different delimiter:

my $str = 'foober';
$str ~~ s!foo!fox!;
$str ~~ s{b(.)r} = " d$0n";
say $str; # OUTPUT: «fox den␤»

Non-paired characters can simply replace the original slashes. Paired characters, like braces, are used only on the match portion, with the substitution given by assignment (of anything: a string, a routine call, etc.).

S/// non-destructive substitution

say S/o .+ d/new/ with 'old string';      # OUTPUT: «new string␤»
S:g/« (.)/$0.uc()/.say for <foo bar ber>; # OUTPUT: «Foo␤Bar␤Ber␤»

S/// uses the same semantics as the s/// operator, except it leaves the original string intact and returns the resultant string instead of $/ ($/ still being set to the same values as with s///).

Note: since the result is obtained as a return value, using this operator with the ~~ smartmatch operator is a mistake and will issue a warning. To execute the substitution on a variable that isn't the $_ this operator uses, alias it to $_ with given, with, or any other way. Alternatively, use the .subst method.

tr/// in-place transliteration

my $str = 'old string';
$str ~~ tr/dol/wne/;
say $str; # OUTPUT: «new string␤»

tr/// operates on the $_ topical variable and changes it in place. It behaves similar to Str.trans called with a single Pair argument, where key is the matching part (characters dol in the example above) and value is the replacement part (characters wne in the example above). Accepts the same adverbs as Str.trans. Returns the StrDistance object that measures the distance between original value and the resultant string.

my $str = 'old string';
$str ~~ tr:c:d/dol st//;
say $str; # OUTPUT: «ring␤»

TR/// non-destructive transliteration

with 'old string' {
    say TR/dol/wne/; # OUTPUT: «new string␤»
}

TR/// behaves the same as the tr/// operator, except that it leaves the $_ value untouched and instead returns the resultant string.

say TR:d/dol // with 'old string'; # OUTPUT: «string␤»

Assignment operators

Infix operators can be combined with the assignment operator to modify a value and apply the result to a container in one go. Containers will be autovivified if possible. Some examples:

my $a = 32;
$a += 10;     # 42
$a -= 2;      # 40

$a = 3;
$a min= 5;    # still 3
$a min= 2;    # 2

my $s = 'a';
$s ~= 'b';    # 'ab'

This behavior is automatically extended to include custom-defined infix operators.

sub infix:<space-concat> ($a, $b) { $a ~ " " ~ $b };
my $a = 'word1';
$a space-concat= 'word2';     # RESULT: «'word1 word2'»

Although not strictly operators, methods can be used in the same fashion.

my Real $a = 1/2;
$a = 3.14;
$a .= round;      # RESULT: «3»

Negated relational operators

The result of a relational operator returning Bool can be negated by prefixing with !. To avoid visual confusion with the !! operator, you may not modify any operator already beginning with !.

There are shortcuts for !== and !eq, namely != and ne.

my $a = True;
say so $a != True;    # OUTPUT: «False␤»
my $i = 10;

my $release = Date.new(:2015year, :12month, :24day);
my $today = Date.today;
say so $release !before $today;     # OUTPUT: «False␤»

Reversed operators

Any infix operator may be called with its two arguments reversed by prefixing with R. Associativity of operands is reversed as well.

say 4 R/ 12;        # OUTPUT: «3␤»
say [R/] 2, 4, 16;  # OUTPUT: «2␤»

Hyper operators

Hyper operators include « and », with their ASCII variants << and >>. They apply a given operator enclosed (or preceded or followed, in the case of unary operators) by « and/or » to one or two lists, returning the resulting list, with the pointy part of « or » aimed at the shorter list. Single elements are turned to a list, so they can be used too. If one of the lists is shorter than the other, the operator will cycle over the shorter list until all elements of the longer list are processed.

say (1, 2, 3) »*» 2;          # OUTPUT: «(2 4 6)␤»
say (1, 2, 3, 4) »~» <a b>;   # OUTPUT: «(1a 2b 3a 4b)␤»
say (1, 2, 3) »+« (4, 5, 6);  # OUTPUT: «(5 7 9)␤»

Assignment metaoperators can be hyped.

my @a = 1, 2, 3;
say @a »+=» 1;    # OUTPUT: «[2 3 4]␤»
my ($a, $b, $c);
(($a, $b), $c) «=» ((1, 2), 3);
say "$a, $c";       #  OUTPUT: «1, 3␤»

Hyper forms of unary operators have the pointy bit aimed at the operator and the blunt end at the list to be operated on.

my @wisdom = True, False, True;
say !« @wisdom;     # OUTPUT: «[False True False]␤»

my @a = 1, 2, 3;
@a»++;              # OUTPUT: «(2, 3, 4)␤»

Hyper operators are defined recursively on nested arrays.

say -« [[1, 2], 3]; # OUTPUT: «[[-1 -2] -3]␤»

Also, methods can be called in an out of order, concurrent fashion. The resulting list is in order. Note that all hyper operators are candidates for autothreading and will cause tears if the methods have side effects. The optimizer has full reign over hyper operators, which is the reason that they cannot be defined by the user.

class CarefulClass { method take-care {} }
my CarefulClass @objs;
my @results = @objs».take-care();

my @slops;        # May Contain Nuts
@slops».?this-method-may-not-exist();

Hyper operators can work with hashes. The pointy direction indicates if missing keys are to be ignored in the resulting hash. The enclosed operator operates on all values that have keys in both hashes.

%foo «+» %bar; intersection of keys
%foo »+« %bar; union of keys
%outer »+» %inner; only keys of %inner that exist in %outer will occur in the result
my %outer = 1, 2, 3 Z=> <a b c>;
my %inner = 1, 2 Z=> <x z>;
say %outer «~» %inner;          # OUTPUT: «{"1" => "ax", "2" => "bz"}␤»

Hyper operators can take user-defined operators as their operator argument.

sub pretty-file-site (Int $size --> Str) {
    # rounding version of infix:</>(Int, Int)
    sub infix:<r/>(Int \i1, Int \i2) {
        round(i1 / i2, 0.1)
    }

    # we build a vector of fractions of $size and zip that with the fitting prefix
    for $size «[r/]« (2**60, 2**50, 2**40, 2**30, 2**20, 2**10)
              Z      <EB     PB     TB     GB     MB     KB> -> [\v,\suffix] {
        # starting with the biggest suffix,
        # we take the first that is 0.5 of that suffix or bigger
        return v ~ ' ' ~ suffix if v > 0.4
    }
    # this be smaller or equal then 0.4 KB
    return $size.Str;
}

for 60, 50, 40, 30, 20, 10 -> $test {
    my &a = { (2 ** $test) * (1/4, 1/2, 1, 10, 100).pick * (1..10).pick };
    print pretty-file-site(a.Int) xx 2, ' ';
}

# OUTPUT: «10 EB 4 EB 2 PB 5 PB 0.5 PB 4 TB 300 GB 4.5 GB 50 MB 200 MB 9 KB 0.6 MB␤»

Whether hyperoperators descend into child lists depends on the nodality of the inner operator of a chain. For the hyper method call operator (».), the nodality of the target method is significant.

say (<a b>, <c d e>)».elems;        # OUTPUT: «(2 3)␤»
say (<a b>, <c d e>)».&{ .elems };  # OUTPUT: «((1 1) (1 1 1))␤»

You can chain hyper operators to destructure a List of Lists.

my $neighbors = ((-1, 0), (0, -1), (0, 1), (1, 0));
my $p = (2, 3);
say $neighbors »>>+<<» ($p, *);   # OUTPUT: «((1 3) (2 2) (2 4) (3 3))␤»

Reduction metaoperators

The reduction metaoperator, [ ], reduces a list with the given infix operator. It gives the same result as the reduce routine - see there for details.

# These two are equivalent:
say [+] 1, 2, 3;                # OUTPUT: «6␤»
say reduce &infix:<+>, 1, 2, 3; # OUTPUT: «6␤»

No whitespace is allowed between the square brackets and the operator. To wrap a function instead of an operator, provide an additional layer of square brackets:

sub plus { $^a + $^b };
say [[&plus]] 1, 2, 3;          # OUTPUT: «6␤»

The argument list is iterated without flattening. This means that you can pass a nested list to the reducing form of a list infix operator:

say [X~] (1, 2), <a b>;         # OUTPUT: «(1a 1b 2a 2b)␤»

which is equivalent to 1, 2 X~ <a b>.

By default, only the final result of the reduction is returned. Prefix the wrapped operator with a \, to return a lazy list of all intermediate values instead. This is called a "triangular reduce". If the non-meta part contains a \ already, quote it with [] (e.g. [\[\x]]).

my @n = [\~] 1..*;
say @n[^5];         # OUTPUT: «(1 12 123 1234 12345)␤»

Cross operators

The cross metaoperator, X, will apply a given infix operator in order of cross product to all lists, such that the rightmost operator varies most quickly.

1..3 X~ <a b> # RESULT: «<1a, 1b, 2a, 2b, 3a, 3b>␤»

Zip operators

The zip metaoperator (which is not the same thing as Z) will apply a given infix operator to pairs taken one left, one right, from its arguments. The resulting list is returned.

my @l = <a b c> Z~ 1, 2, 3;     # RESULT: «[a1 b2 c3]␤»

If one of the operands runs out of elements prematurely, the zip operator will stop. An infinite list can be used to repeat elements. A list with a final element of * will repeat its 2nd last element indefinitely.

my @l = <a b c d> Z~ ':' xx *;  # RESULT: «<a: b: c: d:>»
   @l = <a b c d> Z~ 1, 2, *;   # RESULT: «<a1 b2 c2 d2>»

If an infix operator is not given, , (comma operator) will be used by default:

my @l = 1 Z 2;  # RESULT: «[(1 2)]»

Sequential operators

The sequential metaoperator, S, will suppress any concurrency or reordering done by the optimizer. Most simple infix operators are supported.

say so 1 S& 2 S& 3;  # OUTPUT: «True␤»

Nesting of metaoperators

To avoid ambiguity when chaining metaoperators, use square brackets to help the compiler understand you.

my @a = 1, 2, 3;
my @b = 5, 6, 7;
@a X[+=] @b;
say @a;         # OUTPUT: «[19 20 21]␤»

Term precedence

term < >

The quote-words construct breaks up the contents on whitespace and returns a List of the words. If a word looks like a number literal or a Pair literal, it's converted to the appropriate number.

say <a b c>[1];   # OUTPUT: «b␤»

term ( )

The grouping operator.

An empty group () creates an empty list. Parentheses around non-empty expressions simply structure the expression, but do not have additional semantics.

In an argument list, putting parenthesis around an argument prevents it from being interpreted as a named argument.

multi sub p(:$a!) { say 'named'      }
multi sub p($a)   { say 'positional' }
p a => 1;           # OUTPUT: «named␤»
p (a => 1);         # OUTPUT: «positional␤»

term { }

Block or Hash constructor.

If the content is empty, or contains a single list that starts with a Pair literal or %-sigiled variable, and the $_ variable or placeholder parameters are not used, the constructor returns a Hash. Otherwise it constructs a Block.

To force construction of a Block, follow the opening brace with a semicolon. To always ensure you end up with a Hash, you can use %( ) coercer or hash routine instead:

{}.^name.say;        # OUTPUT: «Hash␤»
{;}.^name.say;       # OUTPUT: «Block␤»

{:$_}.^name.say;     # OUTPUT: «Block␤»
%(:$_).^name.say;    # OUTPUT: «Hash␤»
hash(:$_).^name.say; # OUTPUT: «Hash␤»

circumfix [ ]

The Array constructor returns an itemized Array that does not flatten in list context.

Method postfix precedence

postcircumfix [ ]

sub postcircumfix:<[ ]>(@container, **@index, 
                         :$k, :$v, :$kv, :$p, :$exists, :$delete) 

Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".

my @alphabet = 'a' .. 'z';
say @alphabet[0];                   # OUTPUT: «a␤»
say @alphabet[1];                   # OUTPUT: «b␤»
say @alphabet[*-1];                 # OUTPUT: «z␤»
say @alphabet[100]:exists;          # OUTPUT: «False␤»
say @alphabet[15, 4, 17, 11].join;  # OUTPUT: «perl␤»
say @alphabet[23 .. *].perl;        # OUTPUT: «("x", "y", "z")␤»

@alphabet[1, 2] = "B", "C";
say @alphabet[0..3].perl            # OUTPUT: «("a", "B", "C", "d")␤»

See Subscripts, for a more detailed explanation of this operator's behavior and for how to implement support for it in custom types.

postcircumfix { }

sub postcircumfix:<{ }>(%container, **@key, 
                         :$k, :$v, :$kv, :$p, :$exists, :$delete) 

Universal interface for associative access to zero or more elements of a %container, a.k.a. "hash indexing operator".

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color{"banana"};                 # OUTPUT: «yellow␤»
say %color{"cherry", "kiwi"}.perl;    # OUTPUT: «("red", "green")␤»
say %color{"strawberry"}:exists;      # OUTPUT: «False␤»

%color{"banana", "lime"} = "yellowish", "green";
%color{"cherry"}:delete;
say %color;             # OUTPUT: «banana => yellowish, kiwi => green, lime => green␤»

See postcircumfix < > and postcircumfix « » for convenient shortcuts, and Subscripts for a more detailed explanation of this operator's behavior and how to implement support for it in custom types.

postcircumfix <>

Decontainerization operator, which extracts the value from a container and makes it independent of the container type.

use JSON::Tiny; 
 
 my $config = from-json('{ "files": 3, "path": "/home/perl6/perl6.pod6" }'); 
 say $config.perl;            # OUTPUT: «${:files(3), :path("/home/perl6/perl6.pod6")}» 
 my %config-hash = $config<>; 
 say %config-hash.perl;       # OUTPUT: «{:files(3), :path("/home/perl6/perl6.pod6")}» 

It's a Hash in both cases, and it can be used like that; however, in the first case it was in item context, and in the second case it has been extracted to its proper context.

postcircumfix < >

Shortcut for postcircumfix { } that quotes its argument using the same rules as the quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color<banana>;               # OUTPUT: «yellow␤»
say %color<cherry kiwi>.perl;     # OUTPUT: «("red", "green")␤»
say %color<strawberry>:exists;    # OUTPUT: «False␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix « »

Shortcut for postcircumfix { } that quotes its argument using the same rules as the interpolating quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
my $fruit = "kiwi";
say %color«cherry "$fruit"».perl;   # OUTPUT: «("red", "green")␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix ( )

The call operator treats the invocant as a Callable and invokes it, using the expression between the parentheses as arguments.

Note that an identifier followed by a pair of parentheses is always parsed as a subroutine call.

If you want your objects to respond to the call operator, implement a method CALL-ME.

postfix .

The operator for calling one method, $invocant.method.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .&

The operator to call a subroutine (with at least one positional argument), such as a method. The invocant will be bound to the first positional argument.

Technically, not a real operator; it's syntax special-cased in the compiler.

my sub f($invocant){ "The arg has a value of $invocant" }
42.&f;
# OUTPUT: «The arg has a value of 42␤»

42.&(-> $invocant { "The arg has a value of $invocant" });
# OUTPUT: «The arg has a value of 42␤»

postfix .=

A mutating method call. $invocant.=method desugars to $invocant = $invocant.method, similar to =.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .^

A meta-method call. $invocant.^method calls method on $invocant's metaclass. It desugars to $invocant.HOW.method($invocant, ...). See the meta-object protocol documentation for more information.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .?

Safe call operator. $invocant.?method calls method method on $invocant if it has a method of such name. Otherwise it returns Nil.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .+

$foo.+meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, it throws a X::Method::NotFound exception.

class A {
  method foo { say "from A"; }
}
class B is A {
  multi method foo { say "from B"; }
  multi method foo(Str) { say "from B (Str)"; }
}
class C is B is A {
  multi method foo { say "from C"; }
  multi method foo(Str) { say "from C (Str)"; }
}

say C.+foo; # OUTPUT: «from C␤from B␤from A␤(True True True)␤»

postfix .*

$foo.*meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, an empty List is returned.

Technically, postfix .+ calls .* at first. Read postfix .+ section to see examples.

postfix ». / postfix >>.

Hyper method call operator. Will call a method on all elements of a List out of order and return the list of return values in order.

my @a = <a b c>;
my @b = @a».ord;                  # OUTPUT: «[97, 98, 99]␤»
sub foo(Str:D $c){ $c.ord * 2 };  # The first parameter of a method is the invocant.
say @a».&foo;                     # So we can pretend to have a method call with a sub that got a good first positional argument.
say @a».&{ .ord};                 # Blocks have an implicit positional arguments that lands in $_. The latter can be omitted for method calls.

Take care to avoid a common mistake of expecting side-effects to occur in order. The following say is not guaranteed to produce the output in order:

@a».say;  # WRONG! Could produce a␤b␤c␤ or c␤b␤a␤ or any other order 

postfix .postfix / .postcircumfix

In most cases, a dot may be placed before a postfix or postcircumfix:

my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same

This can be useful for visual clarity or brevity. For example, if an object's attribute is a function, putting a pair of parentheses after the attribute name will become part of the method call. So, either two pairs of parentheses must be used or a dot has to come before the parentheses to separate it from the method call.

class Operation {
    has $.symbol;
    has &.function;
}
my $addition = Operation.new(:symbol<+>, :function{ $^a + $^b });
say $addition.function()(1, 2);   # OUTPUT: «3␤»
# OR
say $addition.function.(1, 2);    # OUTPUT: «3␤»

If the postfix is an identifier, however, it will be interpreted as a normal method call.

1.i # No such method 'i' for invocant of type 'Int' 

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .:<prefix>

A prefix can be called like a method using colonpair notation. For example:

my $a = 1;
say ++$a;       # OUTPUT: «2␤»
say $a.:<++>;   # OUTPUT: «3␤»

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .::

A class-qualified method call, used to call a method as defined in a parent class or role, even after it has been redefined in the child class.

class Bar {
    method baz { 42 }
}
class Foo is Bar {
    method baz { "nope" }
}
say Foo.Bar::baz;       # OUTPUT: «42␤»

Autoincrement precedence

prefix ++

multi sub prefix:<++>($x is rw) is assoc<non>

Increments its argument by one and returns the updated value.

my $x = 3;
say ++$x;   # OUTPUT: «4␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

prefix --

multi sub prefix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the updated value.

my $x = 3;
say --$x;   # OUTPUT: «2␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

postfix ++

multi sub postfix:<++>($x is rw) is assoc<non>

Increments its argument by one and returns the original value.

my $x = 3;
say $x++;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

Note that this does not necessarily return its argument; e.g., for undefined values, it returns 0:

my $x;
say $x++;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «1␤»

Increment on Str will increment the number part of a string and assign the resulting string to the container. A is rw-container is required.

my $filename = "somefile-001.txt";
say $filename++ for 1..3;
# OUTPUT: «somefile-001.txt␤somefile-002.txt␤somefile-003.txt␤»

postfix --

multi sub postfix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the original value.

my $x = 3;
say $x--;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

Note that this does not necessarily return its argument;e.g., for undefined values, it returns 0:

my $x;
say $x--;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «-1␤»

Decrement on Str will decrement the number part of a string and assign the resulting string to the container. A is rw-container is required. Crossing 0 is prohibited and throws X::AdHoc.

my $filename = "somefile-003.txt";
say $filename-- for 1..3;
# OUTPUT: «somefile-003.txt␤somefile-002.txt␤somefile-001.txt␤»

Exponentiation precedence

infix **

multi sub infix:<**>(Any, Any --> Numeric:D) is assoc<right>

The exponentiation operator coerces both arguments to Numeric and calculates the left-hand-side raised to the power of the right-hand side.

If the right-hand side is a non-negative integer and the left-hand side is an arbitrary precision type (Int, FatRat), then the calculation is carried out without loss of precision.

Symbolic unary precedence

prefix ?

multi sub prefix:<?>(Mu --> Bool:D)

Boolean context operator.

Coerces the argument to Bool by calling the Bool method on it. Note that this collapses Junctions.

prefix !

multi sub prefix:<!>(Mu --> Bool:D)

Negated boolean context operator.

Coerces the argument to Bool by calling the Bool method on it, and returns the negation of the result. Note that this collapses Junctions.

prefix +

multi sub prefix:<+>(Any --> Numeric:D)

Numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it.

prefix -

multi sub prefix:<->(Any --> Numeric:D)

Negative numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it, and then negates the result.

prefix ~

multi sub prefix:<~>(Any --> Str:D)

String context operator.

Coerces the argument to Str by calling the Str method on it.

prefix |

Flattens objects of type Capture, Pair, List, Map and Hash into an argument list.

sub slurpee( |args ){
    say args.perl
};
slurpee( <a b c d>, { e => 3}, 'e' => 'f' => 33 )
# OUTPUT: «\(("a", "b", "c", "d"), {:e(3)}, :e(:f(33)))␤»

Please see the Signature page, specially the section on Captures for more information on the subject.

Outside of argument lists, it returns a Slip, which makes it flatten into the outer list. Inside argument list Positional s are turned into positional arguments and Associative s are turned into named arguments.

prefix ||

TODO

prefix +^

multi sub prefix:<+^>(Any --> Int:D)

Integer bitwise negation operator.

Coerces the argument to Int and does a bitwise negation on the result, assuming two's complement.

prefix ~^

Coerces the argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then flips each bit in that buffer.

Please note that this has not yet been implemented.

prefix ?^

multi sub prefix:<?^>(Mu --> Bool:D)

Boolean bitwise negation operator.

Coerces the argument to Bool and then does a bit flip, which makes it the same as prefix:<!> .

prefix ^

multi sub prefix:<^>(Any --> Range:D)

upto operator.

Coerces the argument to Numeric, and generates a range from 0 up to (but excluding) the argument.

say ^5;         # OUTPUT: «0..^5␤»
for ^5 { }      # 5 iterations

Dotty infix precedence

These operators are like their Method Postfix counterparts, but require surrounding whitespace (before and/or after) to distinguish them.

infix .=

Calls the right-side method on the value in the left-side container, replacing the resulting value in the left-side container.

In most cases, this behaves identically to the postfix mutator, but the precedence is lower:

my $a = -5 
 say ++$a.=abs 
 # OUTPUT: «6␤» 
 say ++$a .= abs 
 # OUTPUT: «Cannot modify an immutable Int␤ 
 #           in block <unit> at <tmp> line 1␤␤» 

infix .

Calls the following method (whose name must be alphabetic) on the left-side invocant.

Note that the infix form of the operator has a slightly lower precedence than postfix .meth.

say -5.abs;      # like: -(5.abs)
# OUTPUT: «-5␤»
say -5 . abs;    # like: (-5) . abs
# OUTPUT: «5␤»
say -5 .abs;     # following whitespace is optional
# OUTPUT: «5␤»

Multiplicative precedence

infix *

multi sub infix:<*>(Any, Any --> Numeric:D)

Multiplication operator.

Coerces both arguments to Numeric and multiplies them. The result is of the wider type. See Numeric for details.

infix /

multi sub infix:</>(Any, Any --> Numeric:D)

Division operator.

Coerces both argument to Numeric and divides the left through the right number. Division of Int values returns Rat, otherwise the "wider type" rule described in Numeric holds.

infix div

multi sub infix:<div>(Int:D, Int:D --> Int:D)

Integer division operator. Rounds down.

infix %

multi sub infix:<%>($x, $y --> Numeric:D)

Modulo operator. Coerces to Numeric first.

Generally the following identity holds:

my ($x, $y) = 1,2;
$x % $y == $x - floor($x / $y) * $y

infix %%

multi sub infix:<%%>($a, $b --> Bool:D)

Divisibility operator. Returns True if $a % $b == 0.

infix mod

multi sub infix:<mod>(Int:D $a, Int:D $b --> Int:D)

Integer modulo operator. Returns the remainder of an integer modulo operation.

infix +&

multi sub infix:<+&>($a, $b --> Int:D)

Numeric bitwise AND operator. Coerces both arguments to Int and does a bitwise AND operation assuming two's complement.

infix +<

multi sub infix:<< +< >>($a, $b --> Int:D)

Integer bit shift to the left.

infix +>

multi sub infix:<< +> >>($a, $b --> Int:D)

Integer bit shift to the right.

infix ~&

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise AND on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~<

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise left shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix ~>

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise right shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix gcd

multi sub infix:<gcd>($a, $b --> Int:D)

Coerces both arguments to Int and returns the greatest common divisor.

infix lcm

multi sub infix:<lcm>($a, $b --> Int:D)

Coerces both arguments to Int and returns the least common multiple; that is, the smallest integer that is evenly divisible by both arguments.

Additive precedence

infix +

multi sub infix:<+>($a, $b --> Numeric:D)

Addition operator.

Coerces both arguments to Numeric and adds them.

infix -

multi sub infix:<->($a, $b --> Numeric:D)

Subtraction operator.

Coerces both arguments to Numeric and subtracts the second from the first.

infix +|

multi sub infix:<+|>($a, $b --> Int:D)

Integer bitwise OR operator.

Coerces both arguments to Int and does a bitwise OR (inclusive OR) operation.

infix +^

multi sub infix:<+^>($a, $b --> Int:D)

Integer bitwise XOR operator.

Coerces both arguments to Int and does a bitwise XOR (exclusive OR) operation.

infix ~|

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise OR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~^

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise XOR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ?|

multi sub infix:<?|>($a, $b --> Bool:D)

Boolean logical OR operator.

Coerces both arguments to Bool and does a logical OR (inclusive OR) operation.

Replication precedence

infix x

sub infix:<x>($a, $b --> Str:D)

String repetition operator.

Repeats the string $a $b times, if necessary coercing $a to Str and $b Int. Returns an empty string if $b <= 0 .

say 'ab' x 3;           # OUTPUT: «ababab␤»
say 42 x 3;             # OUTPUT: «424242␤»

my $a = 'a'.IO;
my $b = 3.5;
say $a x $b;            # OUTPUT: «aaa␤»

infix xx

multi sub infix:<xx>($a, $b --> List:D)

List repetition operator.

Returns a list of $a repeated and evaluated $b times ($b is coerced to Int). If $b <= 0 , the empty list is returned.

The left-hand side is evaluated for each repetition, so

say [1, 2] xx 5;
# OUTPUT: «([1 2] [1 2] [1 2] [1 2] [1 2])␤»

returns five distinct arrays (but with the same content each time), and

rand xx 3

returns three pseudo random numbers that are determined independently.

The right-hand side can be *, in which case a lazy, infinite list is returned.

Concatenation

infix ~

multi sub infix:<~>(Any,   Any)
multi sub infix:<~>(Str:D, Str:D)
multi sub infix:<~>(Buf:D, Buf:D)

String concatenation operator.

Coerces both arguments to Str and concatenates them. If both arguments are Buf, a combined buffer is returned.

say 'ab' ~ 'c';     # OUTPUT: «abc␤»

infix

multi sub infix:<∘>()
multi sub infix:<∘>(&f)
multi sub infix:<∘>(&f, &g --> Block:D)

Function combinator operator

The function composition operator infix:<∘> or infix:<o> combines two functions, so that the left function is called with the return value of the right function. If the .count of the left function is greater than 1, the return value of the right function will be slipped into the left function.

Both