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 the variables that affect the the Perl 6 executable, how to run the p6doc documentation front-end, 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.

Part of this official documentation has been translated into Chinese. Here's the index to the pages that have been translated.

1 At the beginning


2 Brief introduction

Using Perl 6 official documentation

Documenting a large language like Perl 6 has to balance several contradictory goals, such as being brief whilst being comprehensive, catering to professional developers with wide experience whilst also being accessible to newcomers to the language.

For a quick hands-on introduction, there is a short annotated programming example.

For programmers with experience in other languages, there are a number of Migration guides that compare and contrast the features of Perl 6 with other languages.

A number of Tutorials cover several areas in which Perl 6 is particularly innovative. The section headers should help navigate the remaining documents.

There are a number of useful resources listed elsewhere on the perl6.org site. These include articles, books, slide presentations, and videos.

It has been found that newcomers to Perl 6 often ask questions that indicate assumptions carried over from other programming paradigms. It is suggested that the following sections in the Fundamental topics section should be reviewed first.

3 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; 
 # Single line comments like this one start with '#'. 
 my $file  = open 'scores.txt'; # Comments can also follow code on a line. 
 my @names = $file.get.words; 
 my %matches; 
 my %sets; 
 #`(  Multiple line comments 
      are denoted by a #, then `, then one of {,[, or ( 
      and closed by the corresponding },], and ). 
      Nested pairs of square brackets, curly braces and 
      parentheses are matched, so 
      something like this () will not end the comment. 
      In this case, closed by: ) 
 for $file.lines -> $line { 
     next unless $line; # ignore any empty lines 
     my ($pairing, $result) = $line.split(' | '); 
     my ($p1, $p2)          = $pairing.words; 
     my ($r1, $r2)          = $result.split(':'); 
     %sets{$p1} += $r1; 
     %sets{$p2} += $r2; 
     if $r1 > $r2 { 
     } else { 
   This is another multi-line comment. ] 
 #`{ So is this, though it's not actually multi-line. } 
 my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 
 for @sorted -> $n { 
     my $match-noun = %matches{$n} == 1 ?? 'match' !! 'matches'; 
     my $set-noun   = %sets{$n} == 1 ?? 'set' !! 'sets'; 
     say "$n has won %matches{$n} $match-noun and %sets{$n} $set-noun"; 

This produces the output:

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


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


A Perl 6 program consists of zero or more statements. A statement ends with a semicolon or a curly brace 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.


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.txt, 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; 


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}.

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 braces 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 will hold 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:

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 the key and the value in a Pair.)

if $r1 > $r2 { 
 } else { 

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 $_.


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 { 
     my $match-noun = %matches{$n} == 1 ?? 'match' !! 'matches'; 
     my $set-noun   = %sets{$n} == 1 ?? 'set' !! 'sets'; 
     say "$n has won %matches{$n} $match-noun and %sets{$n} $set-noun"; 

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." The variable $match-noun will store either the string match if the player has won a single match or matches if the player has won zero or more matches. In order to do this, the ternary operator (?? !!) is used. If %matches{$n} == 1 evaluates to True, then match is returned. Otherwise, matches is returned. Either way, the returned value is stored in $match-noun. The same approach applies to <$set-noun>.

The statement 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.


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}␤"; 
 # OUTPUT (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 braces), 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 @flavors = <vanilla peach>; 
 say "we have @flavors";           # OUTPUT: «we have @flavors␤» 
 say "we have @flavors[0]";        # OUTPUT: «we have vanilla␤» 
 # so-called "Zen slice" 
 say "we have @flavors[]";         # OUTPUT: «we have vanilla peach␤» 
 # method calls ending in postcircumfix 
 say "we have @flavors.sort()";    # OUTPUT: «we have peach vanilla␤» 
 # chained method calls: 
 say "we have @flavors.sort.join(', ')"; 
                                   # OUTPUT: «we have peach, vanilla␤» 


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!"; 

4 Migration guides


5 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 need 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.


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.


There are a few differences in syntax between the two languages, starting with how identifiers are defined.


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

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.


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] 

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 other lexical conventions in the syntax page.


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

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 an 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 square 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.


See the documentation for operators for full details on all operators.


, (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 the smartmatch operator

& | ^ 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 that fat arrow 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

These statements include conditionals and loops.


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.


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.


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 semicolons 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"; 


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



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 ~= ':'; 


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 


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 


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.

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.

Named captures

These work in a slightly different way; also they only work in the latest versions of Perl 5.

use v5.22; 
 "þor is mighty" =~ /is (?<iswhat>\w+)/n; 
 say $+{iswhat}; 

The iswhat within a non-capturing group is used to actually capture what is behind, and up to the end of the group (the )). The capture goes to the %+ hash under the key with the name of the capture. In Perl 6 named captures work this way

"þor is mighty" ~~ /is \s+ $<iswhat>=(\w+)/; 
 say $<iswhat>; 

An actual assignment is made within the regular expression; that's the same syntax used for the variable outside it.

TODO more rules. Use L<< C<translate_regex.pl> from Blue Tiger|https://github.com/Util/Blue_Tiger/>> in the meantime.


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

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


Except for UNITCHECK, all of these special blocks exist in Perl 6 as well. In Perl 6, these are called Phasers. But there are some differences!


There is currently no direct equivalent of CHECK blocks in Perl 6. The CHECK phaser in Perl 6 has the same semantics as the UNITCHECK block in Perl 5: it gets run whenever the compilation unit in which it occurs has finished parsing. This is considered a much saner semantic than the current semantics of CHECK blocks in Perl 5. But for compatibility reasons, it was impossible to change the semantics of CHECK blocks in Perl 5, so a UNITCHECK block was introduced in 5.10. Consequently, it was decided that the Perl 6 CHECK phaser would follow the saner Perl 5 UNITCHECK semantics.

No block necessary

In Perl 5, these special blocks must have curly braces, which implies a separate scope. In Perl 6 this is not necessary, allowing these special blocks to share their scope with the surrounding lexical scope.

my $foo;             # Perl 5 
 BEGIN { $foo = 42 } 
BEGIN my $foo = 42;  # Perl 6 

Changed semantics with regards to precompilation

If you put BEGIN and CHECK phasers in a module that is being precompiled, then these phasers will only be executed during precompilation and not when a precompiled module is being loaded. So when porting module code from Perl 5, you may need to change BEGIN and CHECK blocks to INIT blocks to ensure that they're run when loading that module.



Strict mode is now on by default.


Warnings are now on by default.

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


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.


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 


Allows you to write your script in non-ascii or non-utf8. Perl 6 uses, for the time being, only utf8 for its scripts.


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

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


Manipulate where modules are looked up at compile time. The underlying logic is very different from Perl 5, but in the case you are using an equivalent syntax, use lib in Perl 6 works the same as in Perl 5.


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 


No longer relevant: in Perl 6, source code is expected to be in utf8 encoding.


Discouraged in Perl 5. See https://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 the command line flags that Rakudo uses


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


Change your code to use .split manually.


Change your code to use .split manually.


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.


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

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

Replaced with the ++BUG metasyntactic option.


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 
# Perl 6 
     sub MAIN( Int :$xyz ) { 
         say $xyz if $xyz.defined; 
perl6 example.p6 --xyz=5 
 perl6 example.p6 -xyz=5 


Removed. See Removed Syntactic Features.

This is now the default behavior.

This has been eliminated. Several ways to replicate "taint" mode are discussed in Reddit.

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
# 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

Also, be aware that $! is not really relevant for file IO operation failures in Perl 6. An IO operation that fails will return a Failure instead of throwing an exception. If you want to return the failure message, it is in the failure itself, not in $!. To do similar IO error checking and reporting as in Perl 5:

my $fh = open('./bad/path/to/file', :w) or die $fh;

Note: $fh instead of $!. Or, you can set $_ to the failure and die with $_:

my $fh = open('./bad/path/to/file', :w) orelse .die; # Perl 6

Any operation that tries to use the failure will cause the program to fault and terminate. Even just a call to the .self method is sufficient.

my $fh = open('./bad/path/to/file', :w).self;

Capturing 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;
my $captured = run(«echo "$arg"», :out).out.slurp;

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

my $arg = 'Hello';
my $captured = shell("echo $arg", :out).out.slurp;
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 of introducing 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; 


$ 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.


'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; 



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

Rakudo supports this only for modules so far.


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; 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 behavior of being able to selectively import functions? By defining an EXPORT sub inside the module which specifies the functions to be exported and removing the module Bar statement.

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

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, but by an EXPORT sub which specifies the subs in the module we want to make 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 exportable, 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>; 
 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


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!"]␤» 


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

# Perl 5 
     use 5.010; 
     use Getopt::Long; 
         '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 
 perl example.pl --file=foo --length=42 --verbose 
     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 
     Verbosity off 
 perl6 example.p6 --file=foo --length=42 --verbose 
     Verbosity on 
 perl6 example.p6 --length=abc 
       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.



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.



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

6 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 behavior. It also provides references to ecosystem modules that provide the Perl 5 behavior 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.

### Guidelines for contributions:

Headers should contain the text that a Perl 5 user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for unchanged bits that need not appear in the table of contents.

This article does not describe the additions to syntax, nor details of possible improvements. For example, 0 + $string still works, even though we would write it as +$string now. (Blue Tiger will offer a Perl Modernization guide, with step-by-step procedures for translation, along with details of new idioms and "better ways to do it")

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a P5->P6 question not answered here, please add it to the document, even if we don't have a good answer yet. That will be better than losing the information about a real need.

7 Perl 5 to Perl 6 guide - functions

Builtin functions in Perl 5 to Perl 6


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


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


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:


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 behavior as much as possible in Perl 6.


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 behavior as much as possible.


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() 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.


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



[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.


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


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.


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


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 behavior as much as possible.


Works as it does in Perl 5 but must take an argument. The behavior 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 behavior as much as possible, including looking at HOME and LOGDIR.


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).


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 behavior as much as possible.


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 behavior as much as possible.

.head2 chown

chown is not in Perl 6.


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 behavior as much as possible.


chroot is not in Perl 6.


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.


Not supported in Perl 6.

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


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


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.


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 behavior as much as possible.


Not available in Perl 6.

The Perl 6 ecosystem has a module P5math which exports a crypt function that mimics the original Perl 5 behavior 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).


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 behavior as much as possible.


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;.


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;


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.


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


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 behavior as much as possible.


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.


The closest replacement 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!


No equivalent.


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.) Given those caveats, the Perl 6 ecosystem Native::Exec module exports an exec function for Unix-like systems.


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



Appears to do the same thing as in Perl 5.


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 behavior as much as possible.


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 behavior as much as possible.


Appears not to be in Perl 6.


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 behavior as much as possible.


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 behavior as much as possible.


Currently unimplemented.


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.


Perl 6 does not have built-in formats.


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


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


Will not be implemented.

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


Will not be implemented.

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


Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getpriority function that mimics the original Perl 5 behavior 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 behavior 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 behavior 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 behavior 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 behavior 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 behavior as much as possible.

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


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


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

See IO::Glob module in ecosystem


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 behavior as much as possible.


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.


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/)


In Perl 6 an expression must be specified.

Replaced by the adverbial form :16. E. g. :16("aF") returns 175. This is Str->Int.

The opposite result can be achieved (Int->Str) 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 behavior as much as possible.


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.


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 behavior as much as possible.


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 behavior as much as possible.


Currently unimplemented in Perl 6.


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


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


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.


Same as in Perl 5.


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 behavior as much as possible.


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 behavior as much as possible.


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 behavior as much as possible.


Replaced by $?LINE.

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

See link


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


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.


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 behavior as much as possible.


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.


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 behavior as much as possible.


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


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


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 }


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.


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


Works as in Perl 5.


The same in Perl 6.


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


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 behavior as much as possible.


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.


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 behavior as much as possible.


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 behavior as much as possible.


The same in Perl 6.


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 behavior as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.


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.


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 behavior as much as possible.


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.


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 behavior as much as possible.


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 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 behavior as much as possible.


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 behavior as much as possible.


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


Works as in Perl 5, as well as being available as a method: @a.push("foo");. Note: the flattening behavior 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 behavior as much as possible.


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 behavior as much as possible.


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 behavior as much as possible.


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.


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 behavior as much as possible.


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 behavior as much as possible.


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.


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


Unchanged in Perl 6.


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 behavior as much as possible.


Still available in Perl 6.


No equivalent.


No equivalent.

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


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


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 behavior as much as possible.


Not supported in Perl 6.

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


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 behavior as much as possible.


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


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 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 behavior as much as possible.


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 behavior of the function is required.


Not documented in 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 behavior as much as possible.


Not supported in Perl 6.

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


"[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.


No longer in core.


No longer in core.


No longer in core.


Can be found in the IO::Socket class.


Will not be implemented.

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


Will not be implemented.

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


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


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 behavior as much as possible.


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


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


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 behavior as much as possible.


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 behavior as much as possible.


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


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.


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>); .


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.


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)


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)


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 behavior as much as possible.


Available in Perl 6.


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


Available in Perl 6, see state.


study is no more.

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


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.


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 behavior as much as possible.


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

See symlink.


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


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


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


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


As a method on IO::Handle.


Not supported in Perl 6.

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


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

sub lval() {
    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 behavior as much as possible.


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


Not available in Perl 6.

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


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.


Not currently implemented (2018.04).


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 behavior as much as possible.


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 behavior as much as possible.


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 behavior 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.


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 behavior as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.


Works as in Perl 5, as well as being available as a method: @a.unshift("foo");. Note: the flattening behavior 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 behavior as much as possible.


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 behavior as much as possible.


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.


No equivalent.


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


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.


[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.


As with wait, the disposition of this is unclear.


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;
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);
$a.say;                  # says "2"


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


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


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

8 Perl 5 to Perl 6 guide - operators

Operators in Perl 5 to Perl 6: equivalencies and variations


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


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 detailed 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.


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 = [email protected]. 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 +^, except this operates on integers.

C-style Logical And


C-style Logical Or


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, or fat arrow, works similarly to the Perl 5 "fat comma" in that it allows an unquoted (ordinary) 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[] [email protected]/; results in "1 2 3 [email protected]". 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.


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 +> .

9 Perl 5 to Perl 6 guide - syntax

Syntactic differences between Perl 5 and Perl 6

perlsyn - Perl syntax


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


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.


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)".


# 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 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.

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.

10 Perl 5 to Perl 6 guide - special variables

A comparison of special variables in Perl 5 and Perl 6


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


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.


General variables

$ARG, $_

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.

@ARG, @_

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, $b

$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 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"; 


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.

$<digits> ($1, $2, ...)

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.

$MATCH, $&

$/ 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.


$NR, $.

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" 
 # 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.

$^H, %^H, ${^OPEN}

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.

11 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 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 


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" 

Although it does not fit the same exact use cases, 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 



explain how Perl 6 roles compare to Haskell typeclasses


Definitions and signatures


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 





.assuming vs currying

method chaining vs currying



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.



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: https://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 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 




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)


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?


Parser combinators vs grammars


### Guidelines for contributions:

Headers should contain the text that a Haskell user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for identical bits that need not appear in the table of contents.

This article does not describe in detail language features that Haskell doesn't have at all, instead referring to other documents.

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a Haskell to Perl 6 question that is not being answered here, please add it to the document. Even if we do not have a good answer yet, that will be better than losing the information about a real need.

12 JavaScript (Node.js) 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 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 
 // No equivalent to Perl 6 dynamic variables exists. 
 global.foo = 1; // Globally scoped 
 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.

In addition to regular variables, in Perl 6 there are what is known as dynamic variables. Dynamic variables are looked up using the caller's scope, rather than the outer scope. This is what the equivalent variable declarations look like in Perl 6:

my           $foo = 1; # Lexically scoped 
 our          $foo = 1; # Package scoped 
my  constant  foo = 1; # Lexically scoped; constant 
    constant  foo = 1; # Package scoped; constant 
my  $*foo = 1; # Dynamic variable; lexically scoped 
 our $*foo = 1; # Dynamic variable; package scoped 

GLOBAL::<$foo> := 1; # Globally scoped

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.

You may have noticed the $ and $* symbols placed before variable names. These are known as sigils and twigils respectively, and define what container the variable has. Refer to the documentation on variables for more information on sigils, twigils, and 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; 
 logDupe(2);       // OUTPUT: 2 
 console.log(foo); // OUTPUT: 1 

Perl 6 also allows this:

my $foo = 1; 
 sub log-dupe { 
     my $foo = 2; 
     say $foo; 
 log-dupe; # OUTPUT: 2 
 say $foo; # OUTPUT: 1 



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;       # OUTPUT: {} 
 say %bound;         # OUTPUT: {foo => bar} 
 %bound := %unbound; 
 say %bound;         # OUTPUT: {} 


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);   // OUTPUT: true 
 console.log('1' == 1); // OUTPUT: true 
 console.log([] == 0);  // OUTPUT: true 

Similarly, in Perl 6, both operands are cast to Numeric before comparison if they don't share the same type:

say 1 == 1;       # OUTPUT: True 
 say '1' == 1;     # OUTPUT: True 
 say [1,2,3] == 3; # OUTPUT: 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'; # OUTPUT: True 
 say 1 eq '1';   # OUTPUT: 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);   // OUTPUT: true 
 console.log('1' === 1); // OUTPUT: false 
 console.log({} === {}); // OUTPUT: false 
 let obj = {}; 
 let obj2 = obj; 
 console.log(obj === obj2); // OUTPUT: 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;                    # OUTPUT: «True␤» 
 say '1' === 1;                  # OUTPUT: «False␤» 
 say 'ayy lmao' === 'ayy lmao';  # OUTPUT: «True␤» 
 say {} === {};                  # OUTPUT: «False␤» 
 my \hash = {}; 
 my %hash = hash; 
 say hash === %hash; # OUTPUT: False 

In the last case it's the same object, but containers are different, which is why it returns 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}; # OUTPUT: True 
 my \hash = {}; 
 my %hash := hash; 
 say hash eqv %hash; # OUTPUT: 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; # OUTPUT: True 


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 'ayy lmao' ~~ Str; # OUTPUT: True 
 my %hash = a => 1; 
 say 'a' ~~ %hash; # OUTPUT: True 
 my $str = 'abc'; 
 $str ~~ s/abc/def/; # Mutates $str, like foo.replace('abc', 'def') 
 say $str;           # OUTPUT: def 

While we are talking about instanceof, the equivalent to the constructor property on Node.js objects in Perl 6 is the WHAT attribute:

console.log('foo'.constructor); // OUTPUT: String 
say 'foo'.WHAT; # OUTPUT: Str 


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);   // OUTPUT: 3 
 console.log([] + {}); // OUTPUT: [object Object] 
 console.log({} + []); // OUTPUT: 0 

In Perl 6, again, they are converted to a Numeric type, as before:

say 1 + 2;        # OUTPUT: 3 
 say [] + {};      # OUTPUT: 0 
 say {} + [1,2,3]; # OUTPUT: 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; # OUTPUT: 1 
 say 4 %% 3;  # OUTPUT: False 
 say 6 %% 3;  # OUTPUT: True 


Node.js has &, |, ^, ~, <<, >>, >>>, and ~ for bitwise operators:

console.log(1 << 1);  // OUTPUT: 2 
 console.log(1 >> 1);  // OUTPUT: 0 
 console.log(1 >>> 1); // OUTPUT: 0 
 console.log(1 & 1);   // OUTPUT: 1 
 console.log(0 | 1);   // OUTPUT: 1 
 console.log(1 ^ 1);   // OUTPUT: 0 
 console.log(~1);      // OUTPUT: -2 

In Perl 6, there is no equivalent to >>>. All bitwise operators are prefixed with +, however bitwise negation uses +^ instead of ~:

say 1 +< 1; # OUTPUT: 2 
 say 1 +> 1; # OUTPUT: 0 
             # No equivalent for >>> 
 say 1 +& 1; # OUTPUT: 1 
 say 0 +| 1; # OUTPUT: 1 
 say 1 +^ 1; # OUTPUT: 0 
 say +^1;    # OUTPUT: -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; # OUTPUT: 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; # OUTPUT: 0 

Control flow


You should be familiar with how if/else looks in JavaScript:

let diceRoll = Math.ceil(Math.random() * 6) + Math.ceil(Math.random() * 6); 
 if (diceRoll === 2) { 
     console.log('Snake eyes!'); 
 } else if (diceRoll === 16) { 
 } else { 
     console.log(`Rolled ${diceRoll}.`); 

In Perl 6, if/else works largely the same, with a few key differences. One, parentheses are not required. Two, else if is written as elsif. Three, the if clause may be written after a statement:

my Int $dice-roll = ceiling rand * 12 + ceiling rand * 12; 
 if $dice-roll == 2 { 
     say 'Snake eyes!'; 
 } elsif $dice-roll == 16 { 
     say 'Boxcars!'; 
 } else { 
     say "Rolled $dice-roll."; 

Alternatively, though less efficient, this could be written to use if after statements:

my Int $dice-roll = ceiling rand * 12 + ceiling rand * 12; 
 say 'Snake eyes!'        if $dice-roll == 2; 
 say 'Boxcars!'           if $dice-roll == 16; 
 say "Rolled $dice-roll." if $dice-roll != 2 && $dice-roll != 16; 

Perl 6 also has when, which is like if, but if the condition given is true, no code past the when block within the block it's in is executed:

     when True { 
         say 'In when block!'; # OUTPUT: In when block! 
     say 'This will never be output!'; 

Additionally, Perl 6 has with, orwith, and without, which are like if, else if, and else respectively, but instead of checking whether their condition is true, they check if it's defined.


Switch statements are a way of checking for equality between a given value and a list of values and run some code if one matches. case statements define each value to compare to. default, if included, acts as a fallback for when the given value matches no cases. After matching a case, break is typically used to prevent the code from the cases that follow the one matched from being executed, though rarely this is intentionally omitted.

const ranklist = [2, 3, 4, 5, 6, 7, 8, 9, 'Jack', 'Queen', 'King', 'Ace']; 
 const ranks    = Array.from(Array(3), () => ranklist[Math.floor(Math.random() * ranks.length)]); 
 let   score    = 0; 
 for (let rank of ranks) { 
     switch (rank) { 
         case 'Jack': 
         case 'Queen': 
         case 'King': 
             score += 10; 
         case 'Ace'; 
             score += (score <= 11) ? 10 : 1; 
             score += rank; 

In Perl 6, given can be used like switch statements. There is no equivalent to break since when blocks are most commonly used like case statements. One major difference between switch and given is that a value passed to a switch statement will only match cases that are exactly equal to the value; given values are smartmatched (~~) against the when values.

my     @ranklist = [2, 3, 4, 5, 6, 7, 8, 9, 'Jack', 'Queen', 'King', 'Ace']; 
 my     @ranks    = @ranklist.pick: 3; 
 my Int $score    = 0; 
 for @ranks -> $rank { 
     # The when blocks implicitly return the last statement they contain. 
     $score += do given $rank { 
         when 'Jack' | 'Queen' | 'King' { 10                      } 
         when 'Ace'                     { $score <= 11 ?? 10 !! 1 } 
         default                        { $_                      } 

If there are multiple when blocks that match the value passed to given and you wish to run more than one of them, use proceed. succeed may be used to exit both the when block it's in and the given block, preventing any following statements from being executed:

given Int { 
     when Int     { say 'Int is Int';     proceed } 
     when Numeric { say 'Int is Numeric'; proceed } 
     when Any     { say 'Int is Any';     succeed } 
     when Mu      { say 'Int is Mu'               } # Won't output 
 # Int is Int 
 # Int is Numeric 
 # Int is Any 

for, while, and do/while

There are three different types of for loops in JavaScript:

// C-style for loops 
 const letters = {}; 
 for (let ord = 0x61; ord <= 0x7A; ord++) { 
     let letter = String.fromCharCode(ord); 
     letters[letter] = letter.toUpperCase(); 
 // for..in loops (typically used on objects) 
 for (let letter in letters) { 
 # A 
 # B 
 # C 
 # etc. 
 // for..of loops (typically used on arrays, maps, and sets) 
 for (let letter of Object.values(letters)) { 
 # A 
 # B 
 # C 
 # etc. 

Perl 6 for loops most closely resemble for..of loops, since they work on anything as long as it's iterable. C-style loops are possible to write using loop, but this is discouraged since they're better written as for loops using ranges. Like if statements, for may follow a statement, with the current iteration being accessible using the $_ variable (known as "it"). Methods on $_ may be called without specifying the variable:

my Str %letters{Str}; 
 %letters{$_} = .uc for 'a'..'z'; 
 .say for %letters.values; 
 # A 
 # B 
 # C 
 # etc. 

while loops work identically between JavaScript and Perl 6. Perl 6 also has until loops, where instead of iterating until the given condition is false, they iterate until the condition is true.

do/while loops are known as repeat/while loops in Perl 6. Likewise with while, repeat/until loops also exist and loop until the given condition is false.

To write infinite loops in Perl 6, use loop rather than for or while.

In JavaScript, continue is used to skip to the next iteration in a loop, and break is used to exit a loop early:

let primes = new Set(); 
 let i      = 2; 
 do { 
     let isPrime = true; 
     for (let prime of primes) { 
         if (i % prime == 0) { 
             isPrime = false; 
     if (!isPrime) continue; 
 } while (++i < 20); 
 console.log(primes); # OUTPUT: Set { 2, 3, 5, 7, 11, 13, 17, 19 } 

In Perl 6, these are known as next and last respectively. There is also redo, which repeats the current iteration without evaluating the loop's condition again.

next/redo/last statements may be followed by a label defined before an outer loop to make the statement work on the loop the label refers to, rather than the loop the statement is in:

my %primes is SetHash; 
 my Int $i = 2; 
 repeat { 
     next OUTSIDE if $i %% $_ for %primes.keys; 
 } while ++$i < 20; 
 say %primes; # OUTPUT: SetHash(11 13 17 19 2 3 5 7) 


do is not currently a feature in JavaScript, however a proposal has been made to add it to ECMAScript. do expressions evaluate a block and return the result:

constant VERSION        = v2.0.0; 
 constant VERSION_NUMBER = do { 
     my @digits = VERSION.Str.comb(/\d+/); 
     :16(sprintf "%02x%02x%04x", |@digits) 
 say VERSION_NUMBER; # OUTPUT: 33554432 


Creating types

In JavaScript, types are created by making a class (or a constructor in ES5 and earlier). If you've used TypeScript, you can define a type as a subset of other types like so:

type ID = string | number; 

In Perl 6, classes, roles, subsets, and enums are considered types. Creating classes and roles will be discussed in the OOP section of this article. Creating an ID subset can be done like so:

subset ID where Str | Int; 

See the documentation on subset and Junction for more information.

TypeScript enums may have numbers or strings as their values. Defining the values is optional; by default, the value of the first key is 0, the next key, 1, the next, 2, etc. For example, here is an enum that defines directions for extended ASCII arrow symbols (perhaps for a TUI game):

enum Direction ( 
     UP    = '↑', 
     DOWN  = '↓', 
     LEFT  = '←', 
     RIGHT = '→' 

Enums in Perl 6 may have any type as their keys' values. Enum keys (and optionally, values) can be defined by writing enum, followed by the name of the enum, then the list of keys (and optionally, values), which can be done using < >, « », or ( ). ( ) must be used if you want to define values for the enum's keys. Here is the Direction enum as written in Perl 6:

enum Direction ( 
     UP    => '↑', 
     DOWN  => '↓', 
     LEFT  => '←', 
     RIGHT => '→' 

See the documentation on enum for more information.

Using types

In TypeScript, you can define the type of variables. Attempting to assign a value that doesn't match the type of the variable will make the transpiler error out. This is done like so:

enum Name (Phoebe, Daniel, Joe); 
 let name: string = 'Phoebe'; 
 name = Phoebe; # Causes tsc to error out 
 let hobbies: [string] = ['origami', 'playing instruments', 'programming']; 
 let todo: Map<string, boolean> = new Map([ 
     ['clean the bathroom', false], 
     ['walk the dog', true], 
     ['wash the dishes', true] 
 let doJob: (job: string) => boolean = function (job: string): boolean { 
     todo.set(job, true); 
     return true; 

In Perl 6, variables can be typed by placing the type between the declarator (my, our, etc.) and the variable name. Assigning a value that doesn't match the variable's type will throw either a compile-time or runtime error, depending on how the value is evaluated:

enum Name <Phoebe Daniel Joe>; 
 my Str $name = 'Phoebe'; 
 $name = Phoebe; # Throws a compile-time error 
 # The type here defines the type of the elements of the array. 
 my Str @hobbies = ['origami', 'playing instruments', 'programming']; 
 # The type between the declarator and variable defines the type of the values 
 # of the hash. 
 # The type in the curly braces defines the type of the keys of the hash. 
 my Bool %todo{Str} = ( 
     'clean the bathroom' => False, 
     'walk the dog'       => True, 
     'wash the dishes'    => True 
 # The type here defines the return value of the routine. 
 my Bool &do-job = sub (Str $job --> Bool) { 
     %todo{$job} = True; 

Comparing JavaScript and Perl 6 types

Here is a table of some JavaScript types and their equivalents in Perl 6:

JavaScript Perl 6
Object Mu, Any, Hash
Array List, Array, Seq
String Str
Number Int, Num, Rat
Boolean Bool
Map Map, Hash
Set Set, SetHash

Object is both a superclass of all types in JavaScript and a way to create a hash. In Perl 6, Mu is a superclass of all types, though usually you want to use Any instead, which is a subclass of Mu but also a superclass of nearly every type, with Junction being an exception. When using Object as a hash, Hash is what you want to use. One key difference between Object and Hash is that Object preserves the order of its keys; Hash does not by default.

There are three types equivalent to Array. Array is most similar to Array, since it acts as a mutable array. List is similar to Array, but is immutable. Seq is used to create lazy arrays.

String and Str are for the most part used identically.

There are several different types in Perl 6 equivalent to Number, but the three you'll most commonly see are Int, Num, and Rat. Int represents an integer. Num represents a floating-point number, making it the most similar to Number. Rat represents a fraction of two numbers, and is used when Num cannot provide precise enough values.

Boolean and Bool are for the most part used identically.

Map has both a mutable and an immutable equivalent in Perl 6. Map is the immutable one, and Hash is the mutable one. Don't get them mixed up! Like Map in JavaScript, Map and Hash can have any type of key or value, not just strings for keys.

Like Map, Set also has both a mutable and an immutable equivalent in Perl 6. Set is the immutable one, and SetHash is the mutable one.




Object-oriented programming



Asynchronous programming



The networking API


In Perl 6, there are two APIs for dealing with networking: IO::Socket::INET (for synchronous networking), and IO::Socket::Async (for asynchronous networking).

IO::Socket::INET currently only supports TCP connections. Its API resembles that of C's socket API. If you're familiar with that, then it won't take long to understand how to use it. For example, here's an echo server that closes the connection after receiving its first message:

my IO::Socket::INET $server .= new: 
 my IO::Socket::INET $client .= new: :host<localhost>, :port<8000>; 
 $client.print: 'Hello, world!'; 
 my IO::Socket::INET $conn = $server.accept; 
 my Str $msg               = $conn.recv; 
 say $msg; # OUTPUT: Hello, world! 
 say $client.recv; # OUTPUT: Hello, world! 

By default, IO::Socket::INET connections are IPv4 only. To use IPv6 instead, pass :family(PF_INET6) when constructing a server or a client.

In contrast, IO::Socket::Async supports both IPv4 and IPv6 without the need to specify which family you wish to use. It also supports UDP sockets. Here's how you would write the same echo server as above asynchronously (note that Supply.tap is multithreaded; if this is undesirable, use Supply.act instead:

my $supply = IO::Socket::Async.listen('localhost', 8000); 
 my $server = $supply.tap(-> $conn { 
     $conn.Supply.tap(-> $data { 
         say $data; # OUTPUT: Hello, world! 
         await $conn.print: $data; 
 my $client = await IO::Socket::Async.connect('localhost', 8000); 
 $client.Supply.tap(-> $data { 
     say $data; # OUTPUT: Hello, world! 
 await $client.print: 'Hello, world!'; 

The equivalent code in Node.js looks like this:

const net = require('net'); 
 const server = net.createServer(conn => { 
     conn.on('data', data => { 
         console.log(data); # OUTPUT: Hello, world! 
 }).listen(8000, 'localhost'); 
 const client = net.createConnection(8000, 'localhost', () => { 
     client.on('data', data => { 
         console.log(data); # OUTPUT: Hello, world! 
     client.write("Hello, world!"); 


Perl 6 doesn't natively support HTTP/HTTPS. However, CPAN packages such as Cro help fill the gap.


Perl 6 does not currently support the majority of the features that Node.js's DNS module implements. IO::Socket::INET and IO::Socket::Async can resolve hostnames, but features like resolving DNS records and reverse IP lookups are not implemented yet. There are some modules that are a work in progress, such as Net::DNS::BIND::Manage, that aim to improve DNS support.


Punycode support is available through the Net::LibIDN, Net::LibIDN2, and IDNA::Punycode modules on CPAN.

The filesystem API



Modules and packages



13 Python to Perl 6 - nutshell

Learning Perl 6 from Python, in a nutshell

This page is an attempt to provide a way to learn Perl 6 for folks coming from a Python background. We discuss the equivalent syntax in Perl 6 for a number of Python constructs and idioms.

Basic syntax

Hello, world

Let's start with printing "Hello, world!". The put keyword in Perl 6 is the equivalent of print in Python. Like Python 2, parentheses are optional. A newline is added to the end of the line.

Python 2

print "Hello, world!" 

Python 3

print("Hello, world!") 

Perl 6

put "Hello, world!"

There is also the say keyword, which behaves similarly, but will call the gist method of its argument.

Perl 6

my $hello = "Hello, world!";
say $hello;  # also prints "Hello, world!"
             # same as: put $hello.gist

In Python, ' and " are interchangeable. In Perl 6, both may be used for quoting, but double quotes (") signify that interpolation should be performed. For instance, variables that start with a $, and expressions contained in curly braces are interpolated.

Perl 6

my $planet = 'earth';
say "Hello, $planet";   # Hello, earth
say 'Hello, $planet';   # Hello, $planet
say "Hello, planet number { 1 + 2 }"; # Hello, planet number 3

Statement separators

In Python, a newline signifies the end of a statement. There are a few exceptions: A backslash before a newline continues a statement across lines. Also if there is an unmatched opening parentheses, square bracket, or curly brace, the statement continues across lines, until the matching curly braces are closed.

In Perl 6, a semicolon signifies the end of a statement. The semicolon may be omitted if it is the last statement of a block. The semicolon may also be omitted if there is a closing curly brace followed by a newline.


print 1 + 2 + \ 
     3 + 4 
 print ( 1 + 
     2 ) 

Perl 6

say 1 + 2 +
    3 + 4;
say 1 +


In Python, indentation is used to indicate a block. Perl 6 uses curly braces.


if 1 == 2: 
     print "Wait, what?" 
     print "1 is not 2." 

Perl 6

if 1 == 2 {
    say "Wait, what?"
} else {
    say "1 is not 2."

Parentheses are optional in both languages for expressions in conditionals, as shown above.


In Python, variables are declared and initialized at the same time:

foo = 12 
 bar = 19 

In Perl 6, the my declarator declares a lexical variable. A variable can be initialized with =. This variable can either be declared first and later initialized or declared and initialized at once.

my $foo;       # declare
$foo = 12;     # initialize
my $bar = 19;  # both at once

Also, as you may have noticed, variables in Perl 6 usually start with sigils -- symbols indicating the type of their container. Variables starting with a $ hold scalars. Variables starting with an @ hold arrays, and variables starting with a % hold a hash (dict). Sigilless variables, declared with a \ but used without them, are bound to the value they are assigned to and are thus immutable.

Please note that, from now on, we are going to use sigilless variables in most examples just to illustrate the similarity with Python. That is technically correct, but in general we are going to use sigilless variables in places where their immutability (or independence of type, when they are used in signatures) is needed or needs to be highlighted.


s = 10 
 l = [1, 2, 3] 
 d = { a : 12, b : 99 } 
 print s 
 print l[2] 
 print d['a'] 
 # 10, 2, 12 

Perl 6

my $s = 10;
my @l = 1, 2, 3;
my %d = a => 12, b => 99;
my \x = 99;

say $s;
say @l[1];
say %d<a>;  # or %d{'a'}
say x;
# 10, 2, 12, 99


In Python, functions and classes create a new scope, but no other block constructor (e.g. loops, conditionals) creates a scope. In Python 2, list comprehensions do not create a new scope, but in Python 3, they do.

In Perl 6, every block creates a lexical scope.


if True: 
     x = 10 
 print x 
 # x is now 10 

Perl 6

if True { 
     my $x = 10 
 say $x 
 # error, $x is not declared in this scope 
my $x; 
 if True { 
     $x = 10 
 say $x 
 # ok, $x is 10 


x = 10 
 for x in 1, 2, 3: 
 print x 
 # x is 3 

Perl 6

my \x = 10;
for 1, 2, 3 -> \x {
    # do nothing
say x;
# x is 10

Lambdas in Python can be written as blocks or pointy blocks in Perl 6.


l = lambda i: i + 12 

Perl 6

my $l = -> $i { $i + 12 } 

Another Perl 6 idiom for constructing lambdas is the Whatever star, *.

Perl 6

my $l = * + 12    # same as above

A * in an expression will become a placeholder for the argument, and transform the expression into a lambda at compile time. Each * in an expression is a separate positional parameter.

See the section below for more constructs regarding subroutines and blocks.

Another example (from the Python FAQ):


squares = [] 
 for x in range(5): 
     squares.append(lambda: x ** 2) 
 print squares[2]() 
 print squares[4]() 
 # both 16 since there is only one x 

Perl 6

my \squares = [];
for ^5 -> \x {
    squares.append({ x² });
say squares[2]();
say squares[4]();
# 4, 16 since each loop iteration has a lexically scoped x,

Note that ^N is like range(N). Similarly, N..^M works like range(N, M) (a list from N to M - 1). The range N..M is a list from N to M. The ^ before or after the .. indicates that the beginning or ending endpoint of the list (or both) should be excluded.

Also, is a cute way of writing x ** 2 (which also works fine); the unicode superscript 2 squares a number. Many of the other unicode operators work as you would expect (exponents, fractions, π), but every unicode operator or symbol that can be used in Perl 6 has an ASCII equivalent.

Control flow

Python has for loops and while loops:

for i in 1, 2: 
     print i 
 j = 1 
 while j < 3: 
     print j 
     j += 1 

# 1, 2, 1, 2

Perl 6 also has for loops and while loops:

for 1, 2 -> $i {
    say $i
my $j = 1;
while $j < 3 {
    say $j;
    $j += 1

(Perl 6 also has a few more looping constructs: repeat...until, repeat...while, until, and loop.)

last leaves a loop in Perl 6, and is analogous to break in Python. continue in Python is next in Perl 6.


for i in range(10): 
     if i == 3: 
     if i == 5: 
     print i 

Perl 6

for ^10 -> $i {
    next if $i == 3;
    last if $i == 5;
    say $i;

Using if as a statement modifier (as above) is acceptable in Perl 6, even outside of a list comprehension.

The yield statement within a for loop in Python, which produces a generator, is like a gather/take construct in Perl 6. These both print 1, 2, 3.


def count(): 
     for i in 1, 2, 3: 
         yield i 
 for c in count(): 
     print c 

Perl 6

sub count {
    gather {
        for 1, 2, 3 -> $i {
            take $i

for count() -> $c {
    say $c;

Lambdas, functions and subroutines

Declaring a function (subroutine) with def in Python is accomplished with sub in Perl 6.

def add(a, b): 
     return a + b 
 sub add(\a, \b) { 
     return a + b 

The return is optional; the value of the last expression is used as the return value:

sub add(\a, \b) { 
     a + b 
# using variables with sigils 
 sub add($a, $b) { 
     $a + $b 

Python 2 functions can be called with positional arguments or keyword arguments. These are determined by the caller. In Python 3, some arguments may be "keyword only". In Perl 6, positional and named arguments are determined by the signature of the routine.


def speak(word, times): 
     for i in range(times): 
         print word 
 speak('hi', 2) 
 speak(word='hi', times=2) 

Perl 6

Positional parameters:

sub speak($word, $times) {
  say $word for ^$times
speak('hi', 2);

Named parameters start with a colon:

sub speak(:$word, :$times) {
  say $word for ^$times
speak(word => 'hi', times => 2);
speak(:word<hi>, :times<2>);      # Alternative, more idiomatic

Perl 6 supports multiple dispatch, so several signatures could be made available by declaring a routine as a multi.

multi sub speak($word, $times) {
  say $word for ^$times
multi sub speak(:$word, :$times) {
    speak($word, $times);
speak('hi', 2);
speak(:word<hi>, :times<2>);

Named parameters can be sent using a variety of formats:

sub hello {...};
# all the same
hello(name => 'world'); # fat arrow syntax
hello(:name('world'));  # pair constructor
hello :name<world>;     # <> quotes words and makes a list
my $name = 'world';
hello(:$name);          # lexical var with the same name

Creating an anonymous function can be done with sub, with a block or with a pointy block.


square = lambda x: x ** 2 

Perl 6

my $square = sub ($x) { $x ** 2 };  # anonymous sub
my $square = -> $x { $x ** 2 };     # pointy block
my $square = { $^x ** 2 };          # placeholder variable
my $square = { $_ ** 2 };           # topic variable

Placeholder variables are lexicographically ordered to form positional parameters. Thus these are the same:

my $power = { $^x ** $^y };
my $power = -> $x, $y { $x ** $y };

List comprehensions

Postfix statement modifiers and blocks can be combined to easily create list comprehensions in Perl 6.


print [ i * 2 for i in 3, 9 ]                      # OUTPUT: «[6, 18]␤» 

Perl 6

say ( $_ * 2 for 3, 9 );                           # OUTPUT: «(6 18)␤»
say ( { $^i * 2 } for 3, 9 );                      # OUTPUT: «(6 18)␤»
say ( -> \i { i * 2 } for 3, 9 );                  # OUTPUT: «(6 18)␤»

Conditionals can be applied, but the if keyword comes first, unlike in Python where the if comes second.

print [ x * 2 for x in 1, 2, 3 if x > 1 ]          # OUTPUT: «[4, 6]␤» 


say ( $_ * 2 if $_ > 1 for 1, 2, 3 );              # OUTPUT: «(4 6)␤»

For nested loops, the cross product operator X will help:

print [ i + j for i in 3,9 for j in 2,10 ]         # OUTPUT: «[5, 13, 11, 19]␤» 

becomes either of these:

say ( { $_[0] + $_[1] } for (3,9) X (2,10) );      # OUTPUT: «(5 13 11 19)␤»
say ( -> (\i, \j) { i + j } for (3,9) X (2,10) );  # OUTPUT: «(5 13 11 19)␤»
say ( -> ($i, $j) { $i + $j } for (3,9) X (2,10) );# OUTPUT: «(5 13 11 19)␤»
say ( { $^a[0] + $^a[1] } for (3,9) X (2,10) );    # OUTPUT: «(5 13 11 19)␤»

Using map (which is just like Python's map) and grep (which is like Python's filter) is an alternative.

Classes and objects

Here's an example from the Python docs. First let's go over "instance variables" which are known as attributes in Perl 6:


class Dog: 
     def __init__(self, name): 
         self.name = name 

Perl 6:

class Dog {
    has $.name;

For each created class, Perl 6 provides the constructor method new by default which takes named arguments.


d = Dog('Fido') 
 e = Dog('Buddy') 
 print d.name 
 print e.name 

Perl 6

my $d = Dog.new(:name<Fido>); # or: Dog.new(name => 'Fido') 
 my $e = Dog.new(:name<Buddy>); 
 say $d.name; 
 say $e.name; 

Class attributes in Perl 6 can be declared in a few ways. One way is to just declare a lexical variable and a method for accessing it.


class Dog: 
     kind = 'canine'                # class attribute 
     def __init__(self, name): 
         self.name = name           # instance attribute 
 d = Dog('Fido') 
 e = Dog('Buddy') 
 print d.kind 
 print e.kind 
 print d.name 
 print e.name 

Perl 6:

class Dog {
    my $kind = 'canine';           # class attribute
    method kind { $kind }
    has $.name;                    # instance attribute

my $d = Dog.new(:name<Fido>);
my $e = Dog.new(:name<Buddy>);
say $d.kind;
say $e.kind;
say $d.name;
say $e.name;

In order to mutate attributes in Perl 6, you must use the is rw trait on the attributes:


class Dog: 
     def __init__(self, name): 
         self.name = name 
 d = Dog() 
 d.name = 'rover' 

Perl 6:

class Dog {
    has $.name is rw;
my $d = Dog.new;
$d.name = 'rover';

Inheritance is done using is:


class Animal: 
     def jump(self): 
         print ("I am jumping") 
 class Dog(Animal): 
 d = Dog() 

Perl 6

class Animal {
    method jump {
        say "I am jumping"

class Dog is Animal {

my $d = Dog.new;

Multiple inheritance is possible by using the is trait as many times as required. Alternatively, it can be used in conjunction with the also keyword.


class Dog(Animal, Friend, Pet): 

Perl 6

class Animal {}; class Friend {}; class Pet {};
class Dog is Animal is Friend is Pet {};


class Animal {}; class Friend {}; class Pet {};
class Dog is Animal {
    also is Friend;
    also is Pet;


Decorators in Python are a way of wrapping a function in another one. In Perl 6, this is done with wrap.


def greeter(f): 
     def new(): 
         print 'hello' 
     return new 
 def world(): 
     print 'world' 

Perl 6

sub world {
    say 'world'

&world.wrap(sub () {
    say 'hello';


An alternative would be to use a trait:

# declare the trait 'greeter'
multi sub trait_mod:<is>(Routine $r, :$greeter) {
    $r.wrap(sub {
        say 'hello';

sub world is greeter {
    say 'world';


Context managers

Context managers in Python declare actions that happen when entering or exiting a scope.

Here's a Python context manager that prints the strings 'hello', 'world', and 'bye'.

class hello: 
     def __exit__(self, type, value, traceback): 
         print 'bye' 
     def __enter__(self): 
         print 'hello' 
 with hello(): 
     print 'world' 

For "enter" and "exit" events, passing a block as an argument would be one option:

sub hello(Block $b) {
    say 'hello';
    say 'bye';

hello {
    say 'world';

A related idea is 'Phasers' which may be set up to run on entering or leaving a block.

    LEAVE say 'bye';
    ENTER say 'hello';
    say 'world';


In Python 3, the input keyword is used to prompt the user. This keyword can be provided with an optional argument which is written to standard output without a trailing newline:

user_input = input("Say hi → ") 

When prompted, you can enter Hi or any other string, which will be stored in the user_input variable. This is similar to prompt in Perl 6:

my $user_input = prompt("Say hi → ");
say $user_input; # OUTPUT: whatever you entered.

14 Ruby to Perl 6 - nutshell

Learning Perl 6 from Ruby, in a nutshell: what do I already know?

This page attempts to index the high-level differences in syntax and semantics between Ruby and Perl 6. Whatever works in Ruby and must be written differently in Perl 6 should be listed here (whereas many Perl 6 features and idioms won't be).

Hence 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 Ruby background.

Basic syntax

Statement ending semicolons

Ruby detects the end of most statements with a newline (and a few exceptions), as long as the expression is complete. It is common break up a long expression by leaving an operator dangling at the end of a line to ensure that the parsing will continue:

foo +     # In Ruby a trailing operator means parsing should continue 
   bar + 

In Perl 6 you must explicitly terminate statements with a ;, which allows for better feedback and more flexibility in breaking up long lines. Two exceptions not needing an explicit ; are the last statement in a block, and after the closing curly brace of the block itself (if there is nothing else on that line):

my $x;
if 5 < $x < 10 {
  say "Yep!";
  $x = 17         # No ; required before closing }
}                 # No ; required after closing } because of the newline
say "Done!";      # The ; is not required here if nothing follows


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

# unidiomatic but valid Ruby 
 puts"Hello "+ 
 (people [ i] 
     . name 
     ) . upcase+"!"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 Ruby, 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 an array variable and its square brackets), but there are a few that will unfortunately conflict with some Ruby hackers' habitual coding styles:

if(a < 0); ...; end         # OK in Ruby 
my $a; ...; 
 if ($a < 0) { ... }         # Perl 6 
 if $a < 0 { ... }           # Perl 6, more idiomatic 
while(x > 5); ...; end      # OK in Ruby 
my $x; ...; 
 while ($x > 5) { ... }      # Perl 6 
 while $x > 5 { ... }        # Perl 6, more idiomatic 

. Method calls, .send

Method call syntax uses a dot just like Ruby:

person.name    # Ruby 
my $person; ...; 
 $person.name   # Perl 6 

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

object.send(methodname, args);  # Ruby 
my $object; my Str $methodname; my @args; ...; 
 $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.

Variables, sigils, scope, and common types

In Ruby, variables use sigils primarily to indicate scope. $ for global scope, @@ for class scope, @ for instance scope, and no sigil for local variables (including parameters). The & sigil is also used to indicate method references. Symbols are prefixed with :, but they are not variable and so not really sigils.

In Perl 6 sigils are primarily used to indicate a role that the contained value implements, indicating the type (or at least the interface) of the value. The sigils are invariant, no matter how the variable is being used - you can think of them as part of the variable's name.

The scope of a variable is instead indicated by the declaration itself (my, has, our, etc).

Variable scope

For local variables, Ruby uses implicit variable declaration upon assignment and limited to the current block. In Ruby the content of an if or while built-in construct is not a block or scope.

Perl 6 uses explicit scope indicators, and never creates variables implicitly. Every place you see { ... } is a scope, including the body of a conditional or loop. The commonly used scope declarations:

foo = 7        # Ruby, variable scope is defined by first assignment and 
                # extends to the end of the current block 
my  $foo = 7;   # Perl 6, lexical scoped to the current block 
 our $foo = 7;   # Perl 6, package scoped 
 has $!foo = 7;  # Perl 6, instance scoped (attribute) 

$ Scalar

The $ sigil is always used with "scalar" variables (e.g. $name). These are single-value containers.

This is the most general-purpose variable type, with no restrictions on its contents. Note that you can still address/use its contents, like $x[1], $x{"foo"}, and $f("foo").

@ Array

The @ sigil is always used with "array" variables (e.g. @months, @months[2], @months[2, 4] for an array slice). Variables using the @ sigil can only contain things that do the Positional role, indicating positional indexing and slicing capabilities.

% Hash

The % sigil is always used with "hash" variables (e.g. %calories, %calories<apple>, %calories<pear plum>). Variables using the % sigil can only contain things that do the Associative role.

Ruby uses square brackets to access values for both Arrays and Hashes. Perl 6 uses curly braces for hashes instead. The angle brackets version is available which always autoquotes its contents (strings without quotes):

Adverbs can be used to control the type of slice.

& Sub

The & sigil is used very similarly to Ruby's & 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". Variables using the & sigil can only contain things that do the Callable role.

add = -> n, m { n + m } # Ruby lambda for an addition function 
 add.(2, 3)              # => 5, Ruby invocation of a lambda 
 add.call(2, 3)          # => 5, Ruby invocation of a lambda 
my &add = -> $n, $m { $n + $m }; # Perl 6 addition function 
 &add(2, 3);                      # => 5, you can keep the sigil 
 add(2, 3);                       # => 5, and it works without it 
foo_method = &foo;     # Ruby 
sub foo { ... }; 
 my &foo_method = &foo; # Perl 6 
some_func(&say) # Ruby pass a function reference 
sub some_func { ... }; 
 some_func(&say) # Perl 6 passes function references the same way 

Often in Ruby we pass a block as the last parameter, which is especially used for DSLs. This can be an implicit parameter called by yield, or an explicit block prefixed with &. In Perl 6 a Callable parameter is always listed and called by the variable name (instead of yield), and there are a variety of ways of invoking the function.

# Ruby, declare a method and call the implicit block argument 
 def f 
   yield 2 
 # Ruby, invoke f, pass it a block with 1 argument 
 f do |n| 
   puts "Hi #{n}" 
# Perl 6, declare a method with an explicit block argument 
 sub f(&g:($)) { 
 # Perl 6, invoke f, pass it a block with 1 argument 
 # There are several other ways to do this 
 f(-> $n { say "Hi {$n}" }); # Explicit argument 
 f -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis 
 # Additionally, if 'f' is a method on instance 'obj' you can use ':' 
 # instead of parenthesis 
 my $obj; ...; 
 $obj.f(-> $n { say "Hi {$n}" });  # Explicit argument 
 $obj.f: -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis 

* Slurpy params / argument expansion

In Ruby you can declare an argument to slurp the remainder of the passed parameters into an array using a * prefix. It works similarly in Perl 6:

def foo(*args); puts "I got #{args.length} args!"; end # Ruby 
sub foo(*@args) { say "I got #{@args.elems} args!" }   # Perl 6 

The Perl 6 version above is slightly different in that when it slurps in the arguments into @args, one level of nesting, if any, is automatically removed:

sub foo(*@args) { say @args.perl } 
 foo([1, [2, 3], 4], 5, [6, 7]);   # [1, [2, 3], 4, 5, 6, 7] 

To preserve the structure of the arguments, you can use **:

sub foo(**@args) { say @args.perl } 
 foo([1, [2, 3], 4], 5, [6, 7]);  # [[1, [2, 3], 4], 5, [6, 7]] 

You might want to expand an array into a set of arguments. In Perl 6 this is done using a Slip |:

args = %w(a b c)         # Ruby 
sub foo($q, $r, $s) { ... }; 
 my @args = <a b c>;       # Perl 6 

Perl 6 has many more advanced ways of passing parameters and receiving arguments, see Signatures and Captures.


Perl 6 additionally uses "twigils", which are further indicators about the variable and go between the sigil and the rest of the variable name. Examples:

Variable Description
$foo Scalar with no twigil
$!foo Private instance variable
$.foo Instance variable accessor
$*foo Dynamically scoped variable
$^foo A positional (placeholder) parameter to a block
$:foo A named (placeholder) parameter to a block
$=foo POD (documentation) variables
$?FILE Current source filename. The ? twigil indicates a compile-time value
$~foo Sublanguage seen by parser, uncommon

Though each of these examples use the $ sigil, most could use @ (Positional) or % (Associative).

: Symbols

Perl 6 generally uses strings in the places where Ruby uses symbols. A primary example of this is in hash keys.

address[:joe][:street] # Typical Ruby nested hash with symbol keys 
my %address; ...; 
 %address<joe><street>  # Typical Perl 6 nested hash with string keys 

Perl 6 has colon-pair syntax, which can sometimes look like Ruby symbols.

:age            # Ruby symbol 
# All of these are equivalent for Perl 6 
 :age            ;# Perl 6 pair with implicit True value 
 :age(True)      ;# Perl 6 pair with explicit True value 
 age => True     ;# Perl 6 pair using arrow notation 
 "age" => True   ;# Perl 6 pair using arrow notation and explicit quotes 

You could probably get away with using a colon-pair without an explicit value and pretend that it is a Ruby symbol a lot of the time, but it isn't idiomatic Perl 6.


Many operators have a similar usage in both Ruby and Perl 6:

You may use $x++ instead of x += 1 as a shortcut for incrementing a variable. This can be used as a pre-increment ++$x (increment, return new value) or post-increment $x++ (increment, return old value).

You may use $x-- instead of x -= 1 as a shortcut for decrementing a variable. This can be used as a pre-decrement --$x (decrement, return new value) or post-decrement $x-- (decrement, return old value).

== != < > <= >= Comparisons

Comparisons in Perl 6 are separated between numeric and string to avoid common errors.

For example, using == tries to convert the values to numbers, and eq tries to convert the values to strings.

<=> Three-way comparisons

In Ruby, the <=> operator returns -1, 0, or 1. In Perl 6, they return Order::Less, Order::Same, or Order::More.

<=> forces numeric context for the comparison.

leg ("Less, Equal, or Greater?") forces string context for the comparison.

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

~~ Smartmatch operator

This is a very common matching operator which is similar to === in Ruby. Here are some examples:

my $foo; ...;
say "match!" if $foo ~~ /bar/;       # Regex match
say "match!" if $foo ~~ "bar";       # String match
say "match!" if $foo ~~ :(Int, Str); # Signature match (destructure)

An equivalent in Ruby would be

$foo = 'bar'; 
 puts "match 1!" if /bar/ === $foo;       # Regex match 
 puts "match 2!" if $foo === "bar";       # String match 
 puts "match 3!" if String === $foo;      # Class match 

Please note that, in this case, === is not symmetric; in the first and last case, the variable has to be in the right-hand side. There is no equivalent to the signature class in Ruby, either.

See S03/Smartmatching for more information on this feature.

& | ^ Numeric bitwise ops

& | ^ Boolean ops

In Perl 6, these 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) 

&. Conditional chaining operator

Ruby uses the &. operator to chain methods without raising an error if one invocation returns nil. In Perl 6 use .? for the same purpose.

<< >> Numeric shift left, right ops, shovel operator

Replaced by +< and +> .

puts 42 << 3  # Ruby 
say  42 +< 3; # Perl 6 

Note that Ruby often uses the << operator as the "shovel operator", which is similar to .push. This usage isn't common in Perl 6.

=> and : Key-value separators

In Ruby, => is used in the context of key/value pairs for Hash literal declaration and parameter passing. : is used as a shorthand when the left side is a symbol.

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

If you are using => in a hash literal, then the usage is very similar:

hash = { "AAA" => 1, "BBB" => 2 }  # Ruby, though symbol keys are more common 
my %hash = ( AAA => 1, BBB => 2 ); # Perl 6, uses ()'s though {} usually work 

? : Ternary operator

In Perl 6, this is spelled with two question marks instead of one question mark, and two exclamation points instead of one colon. This deviation from the common ternary operators disambiguates several situations and makes the false-case stand out more.

result     = (  score > 60 )  ? 'Pass'  : 'Fail'; # Ruby 
my $score; ...; 
 my $result = ( $score > 60 ) ?? 'Pass' !! 'Fail'; # Perl 6 

+ String concatenation

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

$food = 'grape' + 'fruit'  # Ruby 
my $food = 'grape' ~ 'fruit'; # Perl 6 

String interpolation

In Ruby, "#{foo}s" deliminates a block embedded in a double-quoted string. In Perl 6 drop the # prefix: "{$foo}s". As in Ruby, you can place arbitrary code into the embedded block and it will be rendered in string context.

Simple variables can be interpolated into a double-quoted string without using the block syntax:

# Ruby 
 name = "Bob" 
 puts "Hello! My name is #{name}!" 
# Perl 6 
 my $name = "Bob"; 
 say "Hello! My name is $name!" 

The result of an embedded block in Ruby uses .to_s to get string context. Perl 6 uses .Str, or .gist for the same affect.

Compound statements


if elsif else unless

This work very similarly between Ruby and Perl 6, but Perl 6 uses { } to clearly delineate the blocks.

# Ruby 
 if x > 5 
     puts "Bigger!" 
 elsif x == 5 
     puts "The same!" 
     puts "Smaller!" 
# Perl 6 
 my $x; ...; 
 if $x > 5 { 
     say "Bigger!" 
 } elsif $x == 5 { 
     say "The same!" 
 } else { 
     say "Smaller!" 

Binding the conditional expression to a variable is a little different:

if x = dostuff(); ...; end   # Ruby 
sub dostuff() {...}; 
 if dostuff() -> $x {...}     # Perl 6, block-assignment uses arrow 

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


The Perl 6 given-when construct is like a chain of if-elsif-else statements or like the case-when construct in Ruby. A big difference is that Ruby uses the == comparison for each condition, but Perl 6 uses the more general smartmatch ~~ operator.

It has the general structure:

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

In its simplest form, the construct is as follows:

my $value; ...;
given $value {
    when "a match" {
        # do-something();
    when "another match" {
        # do-something-else();
    default {
        # do-default-thing();

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


while until

Mostly unchanged; parentheses around the conditions are 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 x = dostuff(); ...; end    # Ruby 
sub dostuff {...}; ...; 
 while dostuff() -> $x {...}      # Perl 6 

for .each

for loops are rare in Ruby, instead we typically use .each on an enumerable. The most direct translation to Perl 6 would be to use .map for both .each and .map, but we typically use a for loop directly.

# Ruby for loop 
 for n in 0..5 
     puts "n: #{n}" 
 # Ruby, more common usage of .each 
 (0..5).each do |n| 
     puts "n: #{n}" 
# Perl 6 
 for 0..5 -> $n { 
     say "n: $n"; 
 # Perl 6, misusing .map 
 (0..5).map: -> $n { 
     say "n: $n"; 

In Ruby, the iteration variable for .each is a copy of the list element, and modifying it does nothing to the original list. Note that it is a copy of the REFERENCE, so you can still change the values to which it refers.

In Perl 6, that alias is read-only (for safety) and thus behaves exactly like Ruby, unless you change -> to <->.

cars.each { |car| ... }    # Ruby; read-only reference 
my @cars; ...; 
 for @cars  -> $car   {...} # Perl 6; read-only 
 for @cars <-> $car   {...} # Perl 6; read-write 

Flow interruption statements

Same as Ruby:

This is last in Perl 6.

Regular expressions ( regex / regexp )

Regular expressions in Perl 6 are significantly different, and more powerful, than in Ruby. By default whitespace is ignored and all characters must be escaped, for example. Regexes can be easily combined and declared in ways to build efficient grammars.

There are many powerful features of Perl 6 regexes, especially defining entire grammars using the same syntax. See Regexes and Grammars.

.match method and =~ operator

In Ruby, regex matches can be done against a variable using the =~ regexp match operator or the .match method. In Perl 6, the ~~ smartmatch op is used instead, or the .match method.

next if line   =~ /static/   # Ruby 
 next if line  !~  /dynamic/; # Ruby 
 next if line.match(/static/) # Ruby 
my $line; ...; 
 next if $line  ~~ /static/;    # Perl 6 
 next if $line !~~ /dynamic/ ;  # Perl 6 
 next if $line.match(/static/); # Perl 6 

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

.sub and .sub!

In Perl 6 you typically use the s/// operator to do regex substitution.

fixed = line.sub(/foo/, 'bar')        # Ruby, non-mutating 
my $line; ...; 
 my $fixed = $line.subst(/foo/, 'bar') # Perl 6, non-mutating 
line.sub!(/foo/, 'bar')   # Ruby, mutating 
my $line; ...; 
 $line ~~ s/foo/bar/;      # Perl 6, mutating 

Regex options

Move any options 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 # Ruby 
my $line; ...; 
 next if $line ~~ m:i/static/; # Perl 6 

Whitespace is ignored, most things must be quoted

In order to aid in readability and reusability, whitespace is not significant in Perl 6 regexes.

/this is a test/ # Ruby, boring string 
 /this.*/         # Ruby, possibly interesting string 
/ this " " is " " a " " test /; # Perl 6, each space is quoted 
 / "this is a test" /;           # Perl 6, quoting the whole string 
 / this .* /;                    # Perl 6, possibly interesting string 

Special matchers generally fall under the <> syntax

There are many cases of special matching syntax that Perl 6 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 look-around assertions:

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

Longest token matching (LTM) displaces alternation

In Perl 6 regexes, | does Longest Token Match (LTM), which decides which alternation wins an ambiguous match based off of a set of rules, rather than about which was written first in the regex.

To avoid the new logic, change any | in your Ruby regex to a ||.

File-related operations

Reading the lines of a text file into an array

Both Ruby and Perl 6 make it easy to read all of the lines in a file into a single variable, and in both cases each line has the newline removed.

lines = File.readlines("file")   # Ruby 
my @lines = "file".IO.lines;     # Perl 6, create an IO object from a string 

Iterating over the lines of a text file

Reading the entire file into memory isn't recommended. The .lines method in Perl 6 returns a lazy sequence, but assigning to an array forces the file to be read. It is better to iterate over the results:

# Ruby 
 File.foreach("file") do |line| 
     puts line 
# Perl 6 
 for "file".IO.lines -> $line { 
     say $line 

Object orientation

Basic classes, methods, attributes

Classes are defined similarly between Ruby and Perl 6, using the class keyword. Ruby uses def for methods, whereas Perl 6 uses method.

# Ruby 
 class Foo 
     def greet(name) 
         puts "Hi #{name}!" 
# Perl 6 
 class Foo { 
     method greet($name) { 
         say "Hi $name!" 

In Ruby you can use an attribute without declaring it beforehand, and you can tell it is an attribute because of the @ sigil. You can also easily create accessors using attr_accessor and its variants. In Perl 6 you use a has declaration and a variety of sigils. You can use the ! twigil for private attributes or . to create an accessor.

# Ruby 
 class Person 
     attr_accessor :age    # Declare .age as an accessor method for @age 
     def initialize 
         @name = 'default' # Assign default value to private instance var 
# Perl 6 
 class Person { 
     has $.age;              # Declare $!age and accessor methods 
     has $!name = 'default'; # Assign default value to private instance var 

Creating a new instance of the class uses the .new method. In Ruby you must manually assign instance variables as needed inside initialize. In Perl 6 you get a default constructor that accepts key/value pairs of accessor attributes, and can do further setup in the BUILD method. Like with Ruby, you can override new itself for more advanced functionality, but this is rare.

# Ruby 
 class Person 
     attr_accessor :name, :age 
     def initialize(attrs) 
         @name = attrs[:name] || 'Jill' 
         @age  = attrs[:age] || 42 
         @birth_year = Time.now.year - @age 
 p = Person.new( name: 'Jack', age: 23 ) 
# Perl 6 
 class Person { 
     has $.name = 'Jill'; 
     has $.age  = 42; 
     has $!birth_year; 
     method BUILD { 
         $!birth_year = now.Date.year - $.age; 
 my $p = Person.new( name => 'Jack', age => 23 ) 

Private methods

Private methods in Perl 6 are declared with a ! prefixed in their name, and are invoked with a ! instead of a ..

# Ruby 
 class Foo 
     def visible 
         puts "I can be seen!" 
     def hidden 
         puts "I cannot easily be called!" 
# Perl 6 
 class Foo { 
     method visible { 
         say "I can be seen!"; 
     method !hidden { 
         say "I cannot easily be called!"; 

An important note is that in Ruby child objects can see parent private methods (so they are more like "protected" methods in other languages). In Perl 6 child objects cannot call parent private methods.

Going meta

Here are a few examples of meta-programming. Note that Perl 6 separates the meta-methods from the regular methods with a caret.

# Ruby 
 person = Person.new 
# Perl 6 
 class Person {}; 
 my $person = Person.new; 
 $person.^name;             # Perl 6, returns Person (class) 
 $person.^methods;          # Perl 6, using .^ syntax to access meta-methods 

Like Ruby, in Perl 6, everything is an object, but not all operations are equivalent to .send. Many operators are global functions that use typed multi-dispatch (function signatures with types) to decide which implementation to use.

5.send(:+, 3)    # => 8, Ruby 
&[+](5, 3)       # => 8, Perl 6, reference to infix addition operator 
 &[+].^candidates # Perl 6, lists all signatures for the + operator 

See Meta-Object Protocol for lots of further details.

Environment variables

Perl module library path

In Ruby, one of the environment variables to specify extra search paths for modules is RUBYLIB.

$ RUBYLIB="/some/module/lib" ruby program.rb 

In Perl 6 this is similar, you merely needs to change the name. As you probably guessed, you just need to use PERL6LIB:

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

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

# Ruby and Perl 6 
 use lib '/some/module/lib'; 


Importing specific functions from a module

In Ruby there is no built-in way to selectively import/export methods from a module.

In Perl 6 you specify 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; # remainder of the file is in 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 you try to use baz an "Undeclared routine" error is raised at compile time.

Some modules allow for selectively importing functions, which would look like:

use Bar <foo>; # Import only foo 
 foo(1);        #=> "foo 1" 
 bar(2);        # Error! 

OptionParser, parsing command-line flags

Command line argument switch parsing in Perl 6 is done by the parameter list of the MAIN subroutine.

# Ruby 
 require 'optparse' 
 options = {} 
 OptionParser.new do |opts| 
     opts.banner = 'Usage: example.rb --length=abc' 
     opts.on("--length", "Set the file") do |length| 
         raise "Length must be > 0" unless length.to_i > 0 
         options[:length] = length 
     opts.on("--filename", "Set the file") do |filename| 
         options[:file] = filename 
     opts.on("--verbose", "Increase verbosity") do |verbose| 
         options[:verbose] = true 
 puts options[:length] 
 puts options[:filename] 
 puts 'Verbosity ', (options[:verbose] ? 'on' : 'off') 
ruby example.rb --filename=foo --length=42 --verbose 
     Verbosity on 
 ruby example.rb --length=abc 
     Length must be > 0 
# Perl 6 
 sub MAIN ( Int :$length where * > 0, :$filename = 'file.dat', Bool :$verbose ) { 
     say $length; 
     say $filename; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
perl6 example.p6 --file=foo --length=42 --verbose 
     Verbosity on 
 perl6 example.p6 --length=abc 
       example.p6 [--length=<Int>] [--file=<Any>] [--verbose] 

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

RubyGems, external libraries

See https://modules.perl6.org/, where a growing number of Perl 6 libraries are available along with the tools to manage them.

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.

You can experiment with Inline::Ruby to call existing Ruby code from your Perl 6 programs. This uses an embedded instance of the ruby interpreter to run Ruby code called from your Perl 6 script. Note that this is an EXPERIMENTAL library. You can similarly call other language's libraries with Inline::Perl5, Inline::Python, and others.

### Guidelines for contributions:

Headers should contain the text that a Ruby user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for identical bits that need not appear in the table of contents.

This article does not describe in detail language features that Ruby doesn't have at all, instead referring to other documents.

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a Ruby to Perl 6 question that is not being answered here, please add it to the document. Even if we do not have a good answer yet, that will be better than losing the information about a real need.

15 Tutorials


16 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 constructor and BUILD implementation. You need to do it for cases in which there are private attributes that might need to be populated during object construction, as in the example below:

# Example taken from 
 # https://medium.freecodecamp.org/a-short-overview-of-object-oriented-software-design-c7aa0a622c83 
 class Hero { 
     has @!inventory; 
     has Str $.name; 
     submethod BUILD( :$name, :@inventory ) { 
         $!name = $name; 
         @!inventory = @inventory 
     method act { 
         return @!inventory.pick; 
 my $hero = Hero.new(:name('Þor'), 
 say $hero.act; 

In this case, we encapsulate the private attribute @!inventory; but private instance variables cannot be set by the default constructor, which is why we add a BUILD submethod that takes care of that.

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; 
             $!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' }) 

In this case, BUILD is needed since we have overridden the default new constructor. bless is eventually 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 as a multi method prevents us from using the default constructor; this implicit constructor uses the attributes as named parameters. This is one of the reasons why using new as a method's name is discouraged. If you need to declare it anyway, use multi method new if you do not want to disable the default constructor.

TWEAK is the last submethod to be called, and it has 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 Object Orientation (OO) document for the mechanics of object construction.

DESTROY is the submethod that gets called when an object is garbage collected. That is going to happen only if the runtime needs the memory, so we can't rely on when it's going to happen. In particular, it could happen in the middle of some running code in a thread, so we must take special care to not assume any context during that event. We can use it to close any kind of handles or supplies or delete temporary files that are no longer going to be used.

my $in_destructor = 0; 
 class Foo { 
     submethod DESTROY { $in_destructor++ } 
 my $foo; 
 for 1 .. 6000 { 
     $foo = Foo.new(); 
 say "DESTROY called $in_destructor times"; 

This might print something like DESTROY called 5701 times, but it only kicks in after we have stomped over former instances of Foo 6000 times. We can't rely, however, on the order of destruction, for instance.

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 the .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!␤» 


In the Task class, the first three lines inside the 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 (i.e., 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 is completed. 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 a private attribute and an accessor method named after the attribute. In this case, both the attribute $!done and the accessor method done are declared. 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 returning 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 a container so external code can modify 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; 

Writable attributes are accessible through writable containers:

class a-class { 
     has $.an-attribute is rw; 
 say (a-class.new.an-attribute = "hey"); # OUTPUT: «hey␤» 

This attribute can also be accessed using the .an-attribute or .an-attribute() syntax. See also the is rw trait on classes for examples on how this works on the whole class.

A class declaration can also include class variables, which are variables whose value is 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; our variables will be shared by subclasses, since they have package scope.

class Str-with-ID is Str { 
     my $counter = 0; 
     our $hierarchy-counter = 0; 
     has Str $.string; 
     has Int $.ID; 
     method TWEAK() { 
         $!ID = $counter++; 
 class Str-with-ID-and-tag is Str-with-ID { 
     has Str $.tag; 
 say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0␤» 
 say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1␤» 
 say Str-with-ID-and-tag.new( string => 'Third', tag => 'Ordinal' ).ID; 
 # OUTPUT: «2␤» 
 say $Str-with-ID::hierarchy-counter;       # OUTPUT: «4␤» 

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 of achieving such effect. Please check the section on submethods for an alternative example on how to do this. Since TWEAK is called in every object instantiation, it's incremented twice when creating objects of class Str-with-ID-and-tag; this is a class hierarchy variable that is shared by all subclasses of Str-with-ID. Additionally, class variables declared with package scope are visible via their fully qualified name (FQN), while lexically scoped class variables are "private".

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 a good idea.

class Singleton { 
     my Singleton $instance; 
     method new {!!!} 
     submethod instance { 
         $instance = Singleton.bless unless $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 instance attributes – that will generate read-only accessors if the attribute is to be public.


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; 
         $!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 (FQN) 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; 
 class B { 
     method i-am-trusted () { 
         my C $c.=new; 
 C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C 

Trust relationships are not subject to inheritance. To trust the global namespace, the pseudo package GLOBAL can be used.


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( 
         :$!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 the 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! 


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.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 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:

my Programmer $o .= new; 
 if $o ~~ Employee { say "It's an employee" }; 
 say $o ~~ GeekCook ?? "It's a geeky cook" !! "Not a geeky cook"; 
 say $o.^name; 
 say $o.perl; 
 say $o.^methods(:local)».name.join(', '); 

The output might look like this:

It's an employee 
 Not a geeky cook 
 Programmer.new(known_languages => ["Perl", "Python", "Pascal"], 
         favorite_editor => "gvim", salary => "too small") 
 code_to_solve, known_languages, favorite_editor 

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, by 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. For instance, 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 to see what's happened. However, this isn't limited to exceptions; 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 class instances; in this case, the class method uses the alembic symbol, and the instance method, defined below it, aggregates the data we have on the cook to show it in a narrative way.

17 Command line interface

Creating your own CLI in Perl 6

Command line interface - an overview

The default command line interface of Perl 6 scripts consists of three parts:

Parsing the command line parameters into a capture

This looks at the values in @*ARGS, interprets these according to some policy, and creates a Capture/type/Capture object out of that. An alternative way of parsing may be provided by the developer or installed using a module.

Calling a provided MAIN subroutine using that capture

Standard multi dispatch is used to call the MAIN subroutine with the generated Capture object. This means that your MAIN subroutine may be a multi sub, each candidate of which is responsible for some part of processing the given command line arguments.

Creating / showing usage information if calling MAIN failed

If multi dispatch failed, then the user of the script should be informed as well as possible as to why it failed. By default, this is done by inspecting the signature of each MAIN candidate sub, and any associated Pod information. The result is then shown to the user on STDERR (or on STDOUT if --help was specified). An alternative way of generating the usage information may be provided by the developer or installed using a module.

sub MAIN

The sub with the special name MAIN will be executed after all relevant entry phasers (BEGIN, CHECK, INIT, PRE, ENTER) have been run and the mainline of the script has been executed. No error will occur if there is no MAIN sub: your script will then just have to do the work, such as argument parsing, in the mainline of the script.

Any normal exit from the MAIN sub will result in an exit code of 0, indicating success. Any return value of the MAIN sub will be ignored. If an exception is thrown that is not handled inside the MAIN sub, then the exit code will be 1. If the dispatch to MAIN failed, a usage message will be displayed on STDERR and the exit code will be 2.

The command line parameters are present in the @*ARGS dynamic variable and may be altered in the mainline of the script before the MAIN unit is called.

The signature of (the candidates of the multi) sub MAIN determines which candidate will actually be called using the standard multi dispatch semantics.

A simple example:

# inside file 'hello.p6'
sub MAIN($name) {
    say "Hello $name, how are you?"

If you call that script without any parameters, you get the following usage message:

$ perl6 hello.p6 
   hello.p6 <name> 

However, if you give a default value for the parameter, running the script either with or without specifying a name will always work:

# inside file 'hello.p6'
sub MAIN($name = 'bashful') {
    say "Hello $name, how are you?"
$ perl6 hello.p6 
 Hello bashful, how are you? 
$ perl6 hello.p6 Liz 
 Hello Liz, how are you? 

Another way to do this is to make sub MAIN a multi sub:

# inside file 'hello.p6'
multi sub MAIN()      { say "Hello bashful, how are you?" }
multi sub MAIN($name) { say "Hello $name, how are you?"   }

Which would give the same output as the examples above. Whether you should use either method to achieve the desired goal is entirely up to you.

A more complicated example using a single positional and multiple named parameters:

# inside "frobnicate.p6" 
 sub MAIN( 
   Str   $file where *.IO.f = 'file.dat', 
   Int  :$length = 24, 
   Bool :$verbose 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 

With file.dat present, this will work this way:

$ perl6 frobnicate.p6 
 Verbosity off 

Or this way with --verbose:

$ perl6 frobnicate.p6 --verbose 
 Verbosity on 

If the file file.dat is not present, or you've specified another filename that doesn't exist, you would get the standard usage message created from introspection of the MAIN sub:

$ perl6 frobnicate.p6 doesntexist.dat 
   frobnicate.p6 [--length=<Int>] [--verbose] [<file>] 

Although you don't have to do anything in your code to do this, it may still be regarded as a bit terse. But there's an easy way to make that usage message better by providing hints using pod features:

# inside "frobnicate.p6" 
 sub MAIN( 
   Str   $file where *.IO.f = 'file.dat',  #= an existing file to frobnicate 
   Int  :$length = 24,                     #= length needed for frobnication 
   Bool :$verbose,                         #= required verbosity 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 

Which would improve the usage message like this:

$ perl6 frobnicate.p6 doesntexist.dat 
   frobnicate.p6 [--length=<Int>] [--verbose] [<file>] 
     [<file>]          an existing file to frobnicate 
     --length=<Int>    length needed for frobnication 
     --verbose         required verbosity 

As any other subroutine, MAIN can define aliases for its named parameters.

sub MAIN( 
   Str   $file where *.IO.f = 'file.dat',  #= an existing file to frobnicate 
   Int  :size(:$length) = 24,              #= length/size needed for frobnication 
   Bool :$verbose,                         #= required verbosity 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 

In which case, these aliases will also be listed as alternatives with --help:

   frobnicate.p6 [--size|--length=<Int>] [--verbose] [<file>] 
     [<file>]                 an existing file to frobnicate 
     --size|--length=<Int>    length needed for frobnication 
     --verbose                required verbosity 


It's possible to alter how arguments are processed before they're passed to sub MAIN {} by setting options in the %*SUB-MAIN-OPTS hash. Due to the nature of dynamic variables, it is required to set up the %*SUB-MAIN-OPTS hash and fill it with the appropriate settings. For instance:

  :named-anywhere,    # allow named variables at any location
  # other possible future options / custom options
sub MAIN ($a, $b, :$c, :$d) {
    say "Accepted!"

Available options are:


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 

is hidden-from-USAGE

Sometimes you want to exclude a MAIN candidate from being shown in any automatically generated usage message. This can be achieved by adding a hidden-from-USAGE trait to the specification of the MAIN candidate you do not want to show. Expanding on an earlier example:

# inside file 'hello.p6'
multi sub MAIN() is hidden-from-USAGE {
    say "Hello bashful, how are you?"
multi sub MAIN($name) {  #= the name by which you would like to be called
    say "Hello $name, how are you?"

So, if you would call this script with just a named variable, you would get the following usage:

$ perl6 hello.p6 --verbose 
   hello.p6 <name> -- the name by which you would like to be called 

Without the hidden-from-USAGE trait on the first candidate, it would have looked like this:

$ perl6 hello.p6 --verbose 
   hello.p6 <name> -- the name by which you would like to be called 

Which, although technically correct, doesn't read as well.

Unit-scoped definition of MAIN

If the entire program body resides within MAIN, you can use the unit declarator as follows (adapting an earlier example):

unit sub MAIN( 
   Str   $file where *.IO.f = 'file.dat', 
   Int  :$length = 24, 
   Bool :$verbose, 
 );  # <- note semicolon here 
 say $length if $length.defined; 
 say $file   if $file.defined; 
 say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 # rest of script is part of MAIN 

Note that this is only appropriate if you can get by with just a single (only) sub MAIN.


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 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'.

The default usage message is available inside sub USAGE via the read-only $*USAGE variable. It will be generated based on available sub MAIN candidates and their parameters. As shown before, you can specify an additional extended description for each candidate using a #|(...) Pod block to set WHY.

Intercepting CLI argument parsing (2018.10, v6.d and later)

You can replace or augment the default way of argument parsing by supplying a ARGS-TO-CAPTURE subroutine yourself, or by importing one from any of the Getopt modules available in the ecosystem.


The ARGS-TO-CAPTURE subroutine should accept two parameters: a Callable representing the MAIN unit to be executed (so it can be introspected if necessary) and an array with the arguments from the command line. It should return a Capture object that will be used to dispatch the MAIN unit. The following is a very contrived example that will create a Capture depending on some keyword that was entered (which can be handy during testing of a command line interface of a script):

sub ARGS-TO-CAPTURE(&main, @args --> Capture) {
    # if we only specified "frobnicate" as an argument
    @args == 1 && @args[0] eq 'frobnicate'
      # then dispatch as MAIN("foo","bar",verbose => 2)
      ?? Capture.new( list => <foo bar>, hash => { verbose => 2 } )
      # otherwise, use default processing of args
      !! &*ARGS-TO-CAPTURE(&main, @args)

Note that the dynamic variable &*ARGS-TO-CAPTURE is available to perform the default command line arguments to Capture processing so you don't have to reinvent the whole wheel if you don't want to.

Intercepting usage message generation (2018.10, v6.d and later)

You can replace or augment the default way of usage message generation (after a failed dispatch to MAIN) by supplying a GENERATE-USAGE subroutine yourself, or by importing one from any of the Getopt modules available in the ecosystem.


Defined as:

sub RUN-MAIN(&main, $mainline, :$in-as-argsfiles)

This routine allows complete control over the handling of MAIN. It gets a Callable that is the MAIN that should be executed, the return value of the mainline execution and additional named variables: :in-as-argsfiles which will be True if STDIN should be treated as $*ARGFILES.

If RUN-MAIN is not provided, a default one will be run that looks for subroutines of the old interface, such as MAIN_HELPER and USAGE. If found, it will execute following the "old" semantics.

class Hero { 
     has @!inventory; 
     has Str $.name; 
     submethod BUILD( :$name, :@inventory ) { 
         $!name = $name; 
         @!inventory = @inventory 
 sub new-main($name, *@stuff ) { 
     Hero.new(:name($name), :inventory(@stuff) ).perl.say 
 RUN-MAIN( &new-main, Nil ); 

This will print the name (first argument) of the generated object.


The GENERATE-USAGE subroutine should accept a Callable representing the MAIN subroutine that didn't get executed because the dispatch failed. This can be used for introspection. All the other parameters are the parameters that were set up to be sent to MAIN. It should return the string of the usage information you want to be shown to the user. An example that will just recreate the Capture that was created from processing the arguments:

sub GENERATE-USAGE(&main, |capture) {
      ?? "You're not allowed to specify a --foo"
      !! &*GENERATE-USAGE(&main, |capture)

You can also use multi subroutines to create the same effect:

multi sub GENERATE-USAGE(&main, :$foo!) {
    "You're not allowed to specify a --foo"
multi sub GENERATE-USAGE(&main, |capture) {
    &*GENERATE-USAGE(&main, |capture)

Note that the dynamic variable &*GENERATE-USAGE is available to perform the default usage message generation so you don't have to reinvent the whole wheel if you don't want to.

Intercepting MAIN calling (before 2018.10, v6.e)

An older interface enabled one to intercept the calling to MAIN completely. This depended on the existence of a MAIN_HELPER subroutine that would be called if a MAIN subroutine was found in the mainline of a program.

This interface was never documented. However, any programs using this undocumented interface will continue to function until v6.e. From v6.d onward, the use of the undocumented API will cause a DEPRECATED message.

Ecosystem modules can provide both the new and the old interface for compatibility with older versions of Perl 6: if a newer Perl 6 recognizes the new (documented) interface, it will use that. If there is no new interface subroutine available, but the old MAIN_HELPER interface is, then it will use the old interface.

If a module developer decides to only offer a module for v6.d or higher, then the support for the old interface can be removed from the module.

18 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


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␤» 
 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 behavior 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 a keyword:

my $promise = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
my $result = await $promise;
say $result;

The subroutine 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 += $_
my $p2 = start {
    my $i = 0;
    for 1 .. 10 {
        $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(

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(

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;
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;

my $promise = get_promise();

# Will throw an exception
# "Access denied to keep/break this Promise; already vowed"
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.


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 {

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 {
$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 {
$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("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;

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;

A live Supply that keeps values until first tapped can be created with Supplier::Preserving.


The whenever keyword can be used in supply blocks or in react blocks. From the 6.d version, it needs to be used within the lexical scope of them. It introduces a block of code that will be run when prompted by an asynchronous event that it specifies - that could be a Supply, a Channel, a Promise or an Iterable.

In this example we are watching two supplies.

my $bread-supplier = Supplier.new; 
 my $vegetable-supplier = Supplier.new; 
 my $supply = supply { 
     whenever $bread-supplier.Supply { 
         emit("We've got bread: " ~ $_); 
     whenever $vegetable-supplier.Supply { 
         emit("We've got a vegetable: " ~ $_); 
 $supply.tap( -> $v { say "$v" }); 
 $vegetable-supplier.emit("Radish");   # OUTPUT: «We've got a vegetable: Radish␤» 
 $bread-supplier.emit("Thick sliced"); # OUTPUT: «We've got bread: Thick sliced␤» 
 $vegetable-supplier.emit("Lettuce");  # OUTPUT: «We've got a vegetable: Lettuce␤» 

Please note that one should keep the code inside the whenever as small as possible, as only one whenever block will be executed at any time. One can use a start block inside the whenever block to run longer running code.


The react keyword introduces a block of code containing one or more whenever keywords to watch asynchronous events. The main difference between a supply block and a react block is that the code in a react block runs where it appears in the code flow, whereas a supply block has to be tapped before it does anything.

Another difference is that a supply block can be used without the whenever keyword, but a react block requires at least one whenever to be of any real use.

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.

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;

Transforming supplies

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 {

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 {

Ending a supply

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).

Phasers in a supply or react block

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.


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;
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 {

    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; 
 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;

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 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");

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


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 }});
# ...

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:


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.


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;
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.


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.


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.


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 {
            my $r = rand;
            sleep $r;

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.

19 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

20 Doing math with Perl 6

Different mathematical paradigms and how they are implemented in this language


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 do 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.


Perl 6 can do arithmetic using different data types. Num, Rat and Complex can all operate as a field under the operations of addition, subtraction, multiplication and division (technically, it should be noted that data types dealing with floating point number representations are not a field in the mathematical sense due to the inherent imprecisions of their arithmetic. However, they constitute an approximate enough, computer friendly version of such mathematical objects for most of the cases). The equivalent mathematical fields are:

Perl 6 class Field

The Ints or ℤ, as they're usually called in mathematics, are not a mathematical field but rather a ring, since they are not closed under multiplicative inverses. However, if the integer division div is used, their operations will always yield other integers; if / is used, on the other hand, 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 to 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␤»

Arithmetic operations are performed by taking into account the type of operands:

say .33-.22-.11 == 0; # OUTPUT: «True␤»

In this case, all numbers are interpreted as Rats, which makes the operation exact. In general, most other languages would interpret them as floating point numbers, which can also be achieved in Perl 6 if needed:

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␤»


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 numbers:

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 has many sequences from the encyclopedia, some of them with their original name, such as ℤ.

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␤»

That said, 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 a set of mathematical constants:

say π; # OUTPUT: «3.141592653589793»
say τ; # Equivalent to 2π; OUTPUT: «6.283185307179586»
say 𝑒; # OUTPUT: «2.718281828459045␤»

These constants are also available through ASCII equivalents: e, pi and tau.

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.

Numerical integration of ordinary differential equations

Perl 6 is an amazing programming language, and of course, you can do a lot of cool math with it. A great amount of work during an applied mathematician's work is to simulate the models they create. For this reason, in every coding language, a numerical integrator is a must-have. Learning how to do this in Perl 6 can be very useful.


In Perl 6 there are some modules in the ecosystem that can make it easier:

For this example we are going to use Math::Model for its useful syntax, but remember that this module requires Math::RungeKutta as well. Simply install them with zef before using these examples.

Malthus model

Let's start with the 'Hello World' of mathematical Ecology: Malthusian growth model. A Malthusian growth model, sometimes called a simple exponential growth model, is essentially exponential growth based on the idea of the function being proportional to the speed to which the function grows. The equation, then, looks like this:

dx/dt = g*x

x(0) = x_0

Where g is the population growth rate, sometimes called Malthusian parameter.

How can we translate that into Perl 6? Well Math::Model brings some help with a very understandable way to do that:

use Math::Model; 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity => 'x', 
     variables   => { 
         velocity           => { $:growth_constant * $:x }, 
         growth_constant    => { 1 }, # basal growth rate 
     initials    => { 
         x       => 3, 
     captures    => ('x'), 
 $m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth malthus.svg', :title('population growth')); 

To fully understand what is going on, let's go through it step by step.

Step by step explanation

At this point our model is set. We need to run the simulation and render a cool plot about our results:

$m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth malthus.svg', :title('population growth')); 

There, we select our time limits and the resolution. Next, we generate a plot. All understood? Well, let's see our result!

link to the image

Looks great! But to be honest, it is quite unrepresentative. Let's explore other examples from more complex situations!

Logistic model

Resources aren't infinite and our population is not going to grow forever. P-F Verhulst thought the same thing, so he presented the logistic model. This model is a common model of population growth, where the rate of reproduction is proportional to both the existing population and the amount of available resources, all else being equal. It looks like this:

dx/dt = g*x*(1-x/k)


where the constant g defines the growth rate and k is the carrying capacity. Modifying the above code we can simulate its behavior in time:

use Math::Model; 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity => 'x', 
     variables   => { 
         velocity           => { $:growth_constant * $:x - $:growth_constant * $:x * $:x / $:k }, 
         growth_constant    => { 1 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
     initials    => { 
         x       => 3, 
     captures    => ('x'), 
 $m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth logistic.svg', :title('population growth')); 

Let's look at our cool plot: link to the image

As you can see population growths till a maximum.

Strong Allee Effect

Interesting, isn't it? Even if these equations seem basic they are linked to a lot of behaviors in our world, like tumor growth. But, before end, let me show you a curious case. Logistic model could be accurate but... What happens when, from a certain threshold, the population size is so small that the survival rate and / or the reproductive rate drops due to the individual's inability to find other ones?

Well, this is an interesting phenomenon described by W.C.Allee, usually known as Allee effect. A simple way to obtain different behaviors associated with this effect is to use the logistic model as a departure, add some terms, and get a cubic growth model like this one:


where all the constants are the same as before and A is called critical point.

Our code would be:

use Math::Model; 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity_x    => 'x', 
     variables   => { 
         velocity_x           => { $:growth_constant * $:x *($:x/$:a -1)*(1- $:x/$:k) }, 
         growth_constant    => { 0.7 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
         a                  => { 15 },  # critical point 
     initials    => { 
         x       => 15, 
     captures    => ('x'), 
 $m.integrate(:from(0), :to(100), :min-resolution(0.5)); 
 $m.render-svg('population growth allee.svg', :title('population growth')); 

Try to execute this one yourself to see the different behaviors that arise when you change the initial condition around the critical point!

Weak Allee Effect

Whilst the strong Allee effect is a demographic Allee effect with a critical population size or density, the weak Allee effect is a demographic Allee effect without a critical population size or density, i.e., a population exhibiting a weak Allee effect will possess a reduced per capita growth rate at lower population density or size. However, even at this low population size or density, the population will always exhibit a positive per capita growth rate. This model differs lightly from the strong one, getting a new formula:

dx/dt=r*x*(1-x/k)*(x/a)**n, with n>0

Our code would be:

use Math::Model; 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity_x => 'x', 
     variables   => { 
         velocity_x           => { $:growth_constant * $:x *(1- $:x/$:k)*($:x/$:a)**$:n }, 
         growth_constant    => { 0.7 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
         a                  => { 15 },  # critical point 
         n                  => { 4  } 
     initials    => { 
         x       => 15, 
     captures    => ('x'), 
 $m.integrate(:from(0), :to(100), :min-resolution(0.5)); 
 $m.render-svg('population growth allee.svg', :title('population growth')); 

Extra info

Do you like physics? Check the original post by the creator of the modules that have been used, Moritz Lenz: https://perlgeek.de/blog-en/perl-6/physical-modelling.html.

21 Entering unicode characters

Input methods for unicode characters in terminals, the shell, and editors

Perl 6 allows the use of unicode characters as variable names. Many operators are defined with unicode symbols (in particular the set/bag operators) as well as some quoting constructs. Hence it is good to know how to enter these symbols into editors, the Perl 6 shell and the command line, especially if the symbols aren't available as actual characters on a keyboard.

General information about entering unicode under various operating systems and environments can be found on the Wikipedia unicode input page.

XCompose (Linux)

Xorg includes digraph support using a Compose key . The default of AltGr + Shift can be remapped to something easier such as Capslock. In GNOME 2 and MATE this can be setup under Preferences → Keyboard → Layouts → Options → Position of Compose Key. So, for example, to input »+« you could type CAPSLOCK > > + CAPSLOCK < <

XCompose allows customizing the digraph sequences using a .XCompose file and https://github.com/kragen/xcompose/blob/master/dotXCompose is an extremely complete one. In GNOME, XCompose was overridden and replaced with a hardcoded list, but it is possible to restore XCompose by setting GTK_IM_MODULE=xim in your environment. It might be necessary to install a xim bridge as well, such as uim-xim.

Getting compose working in all programs

You may have issues using the compose key in all programs. In that case you can try ibus.

 export GTK_IM_MODULE=$input_module 
 export [email protected]=$input_module 
 export QT_IM_MODULE=$input_module 

If you want this to be for all users you can put this in a file /etc/profile.d/compose.sh, which is the easiest way, since you won't have to deal with how different GUI environments set up their environment variables.

If you use KDE you can put this file in ~/.config/plasma-workspace/env/compose.sh and that should work. Other desktop environments will be different. Look up how to set environment variables in yours or use the system-wide option above.


If you have problems entering high codepoint symbols such as 🐧 using the xim input module, you can instead use ibus. You will have to install the ibus package for your distribution. Then you will have to set it to start on load of your Desktop environment. The command that needs to be run is:

ibus-daemon --xim --verbose --daemonize --replace 

Setting --xim should also allow programs not using ibus to still use the xim input method and be backward compatible.


If you are using KDE, open the start menu and type in “Autostart” and click Autostart which should be the first result. In the settings window that opens, click Add program, type in ibus-daemon and click OK. Then go into the Application tab of the window that pops up. In the Command field, enter in the full ibus-daemon command as shown above, with the --desktop option set to --desktop=plasma. Click OK. It should now launch automatically when you log in again.

WinCompose (Windows)

WinCompose adds compose key functionality to Windows. It can be installed either via the WinCompose releases page on GitHub, or with the Chocolatey package manager.

Once the program is installed and running, right click the tray icon and select Options → Composing → Behavior → Compose Key to set your desired key.

WinCompose has multiple sources to choose from in Options → Composing → Sequences. It is recommended to enable XCompose and disable Xorg, as there are a handful of operators which Xorg does not provide sequences for, and Xorg also has sequences which conflict with operator sequences present in XCompose. Sequences can be viewed by right clicking the tray icon and selecting Show Sequences. If you wish to add your own sequences, you can do so by either adding/modifying .XCompose in %USERPROFILE%, or editing user-defined sequences in the options menu.

Terminals, shells, and editors:


Unicode support is enabled in XTerm primarily by setting its utf8 and utf8Fonts options to 1, along with its locale option to UTF-8, in ~/.Xdefaults. Here is a sample configuration that supports displaying enough of unicode to program in Perl 6:

XTerm*faceName:           xft:Noto Mono:style=Regular 
 XTerm*faceNameDoublesize: xft:Noto Emoji:style=Regular 
 XTerm*faceSize:           10 
 XTerm*locale:             UTF-8 
 XTerm*titleModes:         16 
 XTerm*utf8:               1 
 XTerm*utf8Fonts:          1 
 XTerm*utf8Title:          true 


Similarly to XTerm, unicode support is enabled in URxvt primarily by setting its locale option to en_US.UTF-8 in ~/.Xdefaults. Here is a sample configuration that supports displaying enough of unicode to program in Perl 6:

URxvt*font:              xft:Noto Mono:pixelsize=14:style=Regular,\ 
                          xft:Noto Emoji:pixelsize=14:style=Regular 
 URxvt*letterSpace:       -1 
 URxvt*locale:            en_US.UTF-8 
 URxvt*skipBuiltInGlyphs: true 

Unix shell

At the bash shell, one enters unicode characters by using entering Ctrl-Shift-u, then the unicode code point value followed by enter. For instance, to enter the character for the element-of operator (∈) use the following key combination (whitespace has been added for clarity):

Ctrl-Shift-u 2208 Enter 

This also the method one would use to enter unicode characters into the perl6 REPL, if one has started the REPL inside a Unix shell.


GNU Screen does sport a digraph command but with a rather limited digraph table. Thanks to bindkey and exec an external program can be used to insert characters to the current screen window.

bindkey ^K exec .! digraphs 

This will bind control-k to the shell command digraphs. You can use digraphs if you prefer a Perl 6 friendly digraph table over RFC 1345 or change it to your needs.


In Vim, unicode characters are entered (in insert-mode) by pressing first Ctrl-V (also denoted ^V), then u and then the hexadecimal value of the unicode character to be entered. For example, the Greek letter λ (lambda) is entered via the key combination:


You can also use Ctrl-K/^K along with a digraph to type in some characters. So an alternative to the above using digraphs looks like this:


The list of digraphs Vim provides is documented here; you can add your own with the :digraph command.

Further information about entering special characters in Vim can be found on the Vim Wikia page about entering special characters.


The vim-perl6 plugin for Vim can be configured to optionally replace ASCII based ops with their Unicode based equivalents. This will convert the ASCII based ops on the fly while typing them.


In Emacs, unicode characters are entered by first entering the chord C-x 8 RET at which point the text Unicode (name or hex): appears in the minibuffer. One then enters the unicode code point hexadecimal number followed by the enter key. The unicode character will now appear in the document. Thus, to enter the Greek letter λ (lambda), one uses the following key combination:

C-x 8 RET 3bb RET 

Further information about unicode and its entry into Emacs can be found on the Unicode Encoding Emacs wiki page.

You can also use RFC 1345 character mnemonics by typing:

C-x RET C-\ rfc1345 RET 

Or C-u C-\ rfc1345 RET.

To type special characters, type & followed by a mnemonic. Emacs will show the possible characters in the echo area. For example, Greek letter λ (lambda) can be entered by typing:


You can use C-\ to toggle input method.

Another input method you can use to insert special characters is TeX. Select it by typing C-u C-\ TeX RET. You can enter a special character by using a prefix such as \. For example, to enter λ, type:


To view characters and sequences provided by an input method, run the describe-input-method command:

C-h I TeX 

Some characters useful in Perl 6

Smart quotes

These characters are used in different languages as quotation marks. In Perl 6 they are used as quoting characters

Constructs such as these are now possible:

say 「What?!」;
say ”Whoa!“;
say „This works too!”;
say „There are just too many ways“;
say “here: “no problem” at all!”; # You can nest them!

This is very useful in shell:

perl6 -e 'say ‘hello world’' 

since you can just copy and paste some piece of code and not worry about quotes.


These characters are used in French and German as quotation marks. In Perl 6 they are used as interpolation word quotes, hyper operators and as an angle bracket alternative in POD6.

symbol unicode code point ascii equivalent
« U+00AB <<
» U+00BB >>

Thus constructs such as these are now possible:

say (1, 2) »+« (3, 4);     # OUTPUT: «(4 6)␤» - element-wise add
[1, 2, 3] »+=» 42;         # add 42 to each element of @array
say «moo»;                 # OUTPUT: «moo␤»

my $baa = "foo bar";
say «$baa $baa ber».perl;  # OUTPUT: «("foo", "bar", "foo", "bar", "ber")␤»

Set/bag operators

The set/bag operators all have set-theory-related symbols, the unicode code points and their ascii equivalents are listed below. To compose such a character, it is merely necessary to enter the character composition chord (e.g. Ctrl-V u in Vim; Ctrl-Shift-u in Bash) then the unicode code point hexadecimal number.

operator unicode code point ascii equivalent
U+2208 (elem)
U+2209 !(elem)
U+220B (cont)
U+220C !(cont)
U+2286 (<=)
U+2288 !(<=)
U+2282 (<)
U+2284 !(<)
U+2287 (>=)
U+2289 !(>=)
U+2283 (>)
U+2285 !(>)
U+222A (|)
U+2229 (&)
U+2216 (-)
U+2296 (^)
U+228D (.)
U+228E (+)

Mathematical symbols

Wikipedia contains a full list of mathematical operators and symbols in unicode as well as links to their mathematical meaning.

Greek characters

Greek characters may be used as variable names. For a list of Greek and Coptic characters and their unicode code points see the Greek in Unicode Wikipedia article.

For example, to assign the value 3 to π, enter the following in Vim (whitespace added to the compose sequences for clarity):

my $ Ctrl-V u 03C0  = 3;  # same as: my $π = 3; 
 say $ Ctrl-V u 03C0 ;     # 3    same as: say $π; 

Superscripts and subscripts

A limited set of superscripts and subscripts can be created directly in unicode by using the U+207x, U+208x and (less often) the U+209x ranges. However, to produce a value squared (to the power of 2) or cubed (to the power of 3), one needs to use U+00B2 and U+00B3 since these are defined in the Latin1 supplement Unicode block.

Thus, to write the Taylor series expansion around zero of the function exp(x) one would input into e.g. vim the following:

exp(x) = 1 + x + x Ctrl-V u 00B2 /2! + x Ctrl-V u 00B3 /3! 
 + ... + x Ctrl-V u 207F /n! 
 # which would appear as 
 exp(x) = 1 + x + x²/2! + x³/3! + ... + xⁿ/n! 

Or to specify the elements in a list from 1 up to k:

A Ctrl-V u 2081 , A Ctrl-V u 2082 , ..., A Ctrl-V u 2096 
 # which would appear as 
 A₁, A₂, ..., Aₖ 

22 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 { ... } 

As such classes, 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 another 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. For instance:

grammar G { 
     token TOP { <thingy> .* } 
     token thingy { 'Þor' } 
 my $match = G.parse("Þor is mighty"); 
 say $match.perl;     # OUTPUT: «Match.new(made => Any, pos => 13, orig => "Þor is mighty",...» 
 say $/.perl;         # OUTPUT: «Match.new(made => Any, pos => 13, orig => "Þor is mighty",...» 
 say $/<thingy>.perl; 
 # OUTPUT: «Match.new(made => Any, pos => 3, orig => "Þor is mighty", hash => Map.new(()), list => (), from => 0)␤» 

The two first output lines show that $match contains a Match objects with the results of the parsing; but those results are also assigned to the match variable $/. Either match object can be keyed, as indicated above, by thingy to return the match for that particular token.

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; 
 # quote => 「"」 
 # letters => 「enhanced」 
 #quote => 「"」 
 $quoted = "|barred|"; 
 $parsed = Quoted-Other.parse($quoted); 
 say $parsed; 
 #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', 
 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.

23 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; 

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"); 

Or equivalently with say, thus the explicit newline is no longer necessary:

my $fh = open "testfile", :w; 
 $fh.say("data and stuff"); 

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); 

To append to a file, specify the :a option when opening the filehandle explicitly,

my $fh = open "testfile", :a; 
 $fh.print("more data\n"); 

or equivalently with say, thus the explicit newline is no longer necessary,

my $fh = open "testfile", :a; 
 $fh.say("more data"); 

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 "$!"; 

24 Inter-process communication

Programs running other programs and communicating with them

Running programs

Many programs need to be able to run other programs, and we need to pass information to them and receive their output and exit status. 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.

The Proc object

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]";

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;

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';

The Proc::Async object

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 
 # Wait for the program to finish 
 await $done; 

The small program above 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.

25 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 a uniform interface that can be applied to all data structures in the same way. One of these kind of interfaces 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, the iterator method will be called in the appropriate context only when the created object is assigned to a Positional variable, @longer-chain; this variable is an Array and we operate on it as such 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. Then, it also 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 by the role. While Iterable provides the high-level interface loops will be working with, 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 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. An $.index attribute 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 (that will, for instance, keep track of the iteration state, which we are doing now in the main class), such as we did in the previous example; however, this example shows the minimal code needed to build a class that fulfills the iterator and iterable 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.

*Note: Since version 6.d loops can produce a list of values from the values of last statements.*

26 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.


Some tests of module quality.


Here some modules to help you work with NativeCall.

Sample modules

Modules that exist only as minimalist examples, tests for installers, or skeletons.

27 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...␤» 

28 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 that expose Perl 6 constructs.

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 .

Modules 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 used 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.

If it's installed, it will reinstall only if the version of the module is newer than the one 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 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 Class {} 

MyModule::Class will be defined when MyModule is loaded, and you can use it directly employing its fully qualified name (FQN). Classes and other types defined that way are not automatically exported; you will need to explicitly export it if you want to use it by its short name:

# MyModule.pm6 
 unit module MyModule; 
 class Class is export {} 

And then

use MyModule; 
 my $class = Class.new(); 
 say $class.perl; 


use loads and then imports from a compunit at compile time. It will look for files that end in .pm6 (.pm is also supported, but discouraged). See here for where the runtime will look for modules.

use MyModule; 

This is equivalent to:

need  MyModule; 
 import MyModule; 

See also selective importing to restrict what you import.


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
# &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. For instance, that's why 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. Loaded classes are thus registered only in the scope which loaded them in the first place

This change was introduced in late 2016. If you are using versions older than this, behavior will be different
. This means that we will have to use a class in every scope in which we actually employ it.

use Foo;           # Foo has "use Bar" somewhere. 
 use Bar; 
 my $foo = Foo.new; 
 my $bar = Bar.new; 

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 ([email protected])>; 
 our $var is export = 3; 
 sub foo is export { ... }; 
 constant FOO is export = "foobar"; 
 enum FooBar is export <one two three>; 
 # for multi methods, if you declare a proto you 
 # only need to mark the proto with is export 
 proto sub quux(Str $x, |) is export { * }; 
 multi sub quux(Str $x) { ... }; 
 multi sub quux(Str $x, $y) { ... }; 
 # for multi methods, you only need to mark one with is export 
 # but the code is most consistent if all are marked 
 multi sub quux(Str $x) is export { ... }; 
 multi sub quux(Str $x, $y) is export { ... }; 
 # 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             { ... } 
 # objects with tag ':MANDATORY' are always exported 
 sub pants      is export(:MANDATORY) { ... } 
 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; 


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) {} 


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␤» 


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␤» 


To list exported symbols of a module first query the export tags supported by the module.

use URI::Escape;
say URI::Escape::EXPORT::.keys;

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 installed 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.

A prerequisite for this is a PAUSE user account. If you don't have an account already, you can create one here 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.

29 Creating operators

A short tutorial on how to declare operators and create new ones.

Operators are declared by using the sub keyword followed by prefix, infix, postfix, circumfix, or postcircumfix; then a colon and the operator name in a quote construct. For (post-)circumfix operators separate the two parts by white space.

sub hello {
    say "Hello, world!";

say &hello.^name;   # OUTPUT: «Sub␤»
hello;              # OUTPUT: «Hello, world!␤»

my $s = sub ($a, $b) { $a + $b };
say $s.^name;       # OUTPUT: «Sub␤»
say $s(2, 5);       # OUTPUT: «7␤»

# Alternatively we could create a more
# general operator to sum n numbers
sub prefix:<Σ>( *@number-list ) {
    [+] @number-list

say Σ (13, 16, 1); # OUTPUT: «30␤»

sub infix:<:=:>( $a is rw, $b is rw ) {
    ($a, $b) = ($b, $a)

my ($num, $letter) = ('A', 3);
say $num;          # OUTPUT: «A␤»
say $letter;       # OUTPUT: «3␤»

# Swap two variables' values
$num :=: $letter;

say $num;          # OUTPUT: «3␤»
say $letter;       # OUTPUT: «A␤»

sub postfix:<!>( Int $num where * >= 0 ) { [*] 1..$num }
say 0!;            # OUTPUT: «1␤»
say 5!;            # OUTPUT: «120␤»

sub postfix:<♥>( $a ) { say „I love $a!“ }
42♥;               # OUTPUT: «I love 42!␤»

sub postcircumfix:<⸨ ⸩>( Positional $a, Whatever ) {
    say $a[0], '…', $a[*-1]

[1,2,3,4]⸨*⸩;      # OUTPUT: «1…4␤»

constant term:<♥> = "♥"; # We don't want to quote "love", do we?
sub circumfix:<α ω>( $a ) {
    say „$a is the beginning and the end.“

α♥ω;               # OUTPUT: «♥ is the beginning and the end.␤»

These operators use the extended identifier syntax; that is what enables the use of any kind of codepoint to refer to them.

30 Regexes: best practices and gotchas

Some tips on regexes and grammars

To help with robust regexes and grammars, here are some best practices for code layout and readability, what to actually match, and avoiding common pitfalls.

Code layout

Without the :sigspace adverb, whitespace is not significant in Perl 6 regexes. Use that to your own advantage and insert whitespace where it increases readability. Also, insert comments where necessary.

Compare the very compact

my regex float { <[+-]>?\d*'.'\d+[e<[+-]>?\d+]? }

to the more readable

my regex float {
     <[+-]>?        # optional sign
     \d*            # leading digits, optional
     [              # optional exponent
        e <[+-]>?  \d+

As a rule of thumb, use whitespace around atoms and inside groups; put quantifiers directly after the atom; and vertically align opening and closing square brackets and parentheses.

When you use a list of alternations inside parentheses or square brackets, align the vertical bars:

my regex example {
    || <choice_1>
    || <choice_2>
    || <choice_3>

Keep it small

Regexes are often more compact than regular code. Because they do so much with so little, keep regexes short.

When you can name a part of a regex, it's usually best to put it into a separate, named regex.

For example, you could take the float regex from earlier:

my regex float {
     <[+-]>?        # optional sign
     \d*            # leading digits, optional
     [              # optional exponent
        e <[+-]>?  \d+

And decompose it into parts:

my token sign { <[+-]> }
my token decimal { \d+ }
my token exponent { 'e' <sign>? <decimal> }
my regex float {

That helps, especially when the regex becomes more complicated. For example, you might want to make the decimal point optional in the presence of an exponent.

my regex float {
    || <decimal>?  '.' <decimal> <exponent>?
    || <decimal> <exponent>

What to match

Often the input data format has no clear-cut specification, or the specification is not known to the programmer. Then, it's good to be liberal in what you expect, but only so long as there are no possible ambiguities.

For example, in ini files:


What can be inside the section header? Allowing only a word might be too restrictive. Somebody might write [two words], or use dashes, etc. Instead of asking what's allowed on the inside, it might be worth asking instead: what's not allowed?

Clearly, closing square brackets are not allowed, because [a]b] would be ambiguous. By the same argument, opening square brackets should be forbidden. This leaves us with

token header { '[' <-[ \[\] ]>+ ']' }

which is fine if you are only processing one line. But if you're processing a whole file, suddenly the regex parses

[with a 
 newline in between] 

which might not be a good idea. A compromise would be

token header { '[' <-[ \[\] \n ]>+ ']' }

and then, in the post-processing, strip leading and trailing spaces and tabs from the section header.

Matching whitespace

The :sigspace adverb (or using the rule declarator instead of token or regex) is very handy for implicitly parsing whitespace that can appear in many places.

Going back to the example of parsing ini files, we have

my regex kvpair { \s* <key=identifier> '=' <value=identifier> \n+ }

which is probably not as liberal as we want it to be, since the user might put spaces around the equals sign. So, then we may try this:

my regex kvpair { \s* <key=identifier> \s* '=' \s* <value=identifier> \n+ }

But that's looking unwieldy, so we try something else:

my rule kvpair { <key=identifier> '=' <value=identifier> \n+ }

But wait! The implicit whitespace matching after the value uses up all whitespace, including newline characters, so the \n+ doesn't have anything left to match (and rule also disables backtracking, so no luck there).

Therefore, it's important to redefine your definition of implicit whitespace to whitespace that is not significant in the input format.

This works by redefining the token ws; however, it only works for grammars:

grammar IniFormat {
    token ws { <!ww> \h* }
    rule header { \s* '[' (\w+) ']' \n+ }
    token identifier  { \w+ }
    rule kvpair { \s* <key=identifier> '=' <value=identifier> \n+ }
    token section {

    token TOP {

my $contents = q:to/EOI/;
        jack = password1
        joy = muchmoresecure123
        jack = 123
        joy = 42
say so IniFormat.parse($contents);

Besides putting all regexes into a grammar and turning them into tokens (because they don't need to backtrack anyway), the interesting new bit is

token ws { <!ww> \h* }

which gets called for implicit whitespace parsing. It matches when it's not between two word characters (<!ww> , negated "within word" assertion), and zero or more horizontal space characters. The limitation to horizontal whitespace is important, because newlines (which are vertical whitespace) delimit records and shouldn't be matched implicitly.

Still, there's some whitespace-related trouble lurking. The regex \n+ won't match a string like "\n \n", because there's a blank between the two newlines. To allow such input strings, replace \n+ with \n\s*.

31 General reference


32 About the docs


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.


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 


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: 
     =begin code 
     my Code $examples = "amazing"; 
     =end code 
     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.

33 Community

Information about the people working on and using Perl 6


"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

Online communities

There is a large presence on the #perl6 channel on freenode.net, who are happy to provide support and answer questions, or just use as a friendly place to hang 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. More resources can be found in the perl6.org community page.

Offline communities

Perl 6 is also a common topic at Perl conferences and Perl Monger meetings and other meetups. If you prefer in-person meetings, these are warmly recommended!

Other resources

Camelia, the multi-color butterfly with P 6 in her wings, is the symbol of this diverse and welcoming community.

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. If you want a single resource to know what is going on in the Perl community now, this is your best resource.

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/advent repository. If you want to participate, its organization starts by the end of October, so check out the channels above to keep up to date.

HOW TO WRITE: One topic/point/idea per sentence, one sentence per line - to make diffs & translation easier.

34 FAQ

Frequently asked questions about Perl 6


What's the difference between Raku, 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 (which can also be called "Raku") is the definition of the language. When talking about the current interpreter, Rakudo and Perl 6 can be used interchangeably.

When was Perl 6 released?

The Rakudo 2015.12 implementation version was released 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.d.2) or major releases (e.g., v6.e).

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 was v6.d released?

The v6.d Specification was released on Diwali 2018, which was November 6–7 2018, in a convenient time zone. 6.d was enabled by default in the Rakudo compiler release of 2018.11.

The vast majority of 6.d features were already implemented and available 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 behaviors is available automatically if you have the use v6.d pragma at the top of the file. The rest of about 3100 new commits to the language specification simply clarify previously undefined behavior.

As a Perl 6 user, what should I install?

Mac users can use the latest Rakudo Star DMG binary installer at https://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 https://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 a pre-release version of Perl 6.

You can always get help from a live human in our help chat or search the chat logs to find previous conversations and discussions.

Can I get some books about Perl 6?

Here are some available books, in alphabetical order:

A list of books published or in progress is maintained in perl6.org.

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.


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 symlink 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 does 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. Then, Rakudo both stores the compiled bytecode on disk and uses it, 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 a Circular module loading detected error if you have them between your modules.

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 implementing 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 the say routine that uses the gist method which gives the "gist" of the object being dumped. More detailed output can be obtained by calling the perl method that typically returns an object's 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.


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.

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 a runtime error.


sub foo( Int $a, Int $b ) {...} 
 foo(1)     # ===SORRY!=== Error while compiling ... 
say 1/0;   # Attempt to divide 1 by zero using div 

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 by using, for instance, the 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 &&.


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 in the signature.

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); 
 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.

See the Perl 6: Sigils, Variables, and Containers article to learn more.

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?

The say statement in the following code sample

class A { 
     has $!x; 
     method show-x { 
         return $!x; 
 say A.new(x => 5).show-x; 

does not print 5. Private attributes are private, which means invisible to the outside world. If the default constructor could initialize them, they would leak into the public API. Thus, in this particular code sample the attribute $!x isn't initialized during object construction by the default constructor.

If you still want to initialize private attributes with the default constructor, you can add a submethod BUILD to achieve such task:

class B { 
     has $!x; 
     submethod BUILD(:$!x) { } 
     method show-x { 
         return $!x; 
 say 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.

However, you shouldn't do that. If the attribute is declared as private, then it shouldn't be exposed to the environment outside the class (e.g., during object construction). On the other hand, if the attribute is public, there is no downside to declaring it that way with $.x since the external view is read-only 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 convert its arguments to a string by calling the Str method on each item passed to them while say uses the gist method. 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 understanding the essence of the object.

Or phrased differently, $obj.Str gives a string representation, $obj.gist provides 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.

For example, when the Str method is invoked on a type object, also known as an "undefined value", the type is stringified to an empty string and a warning is thrown. On the other hand, 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'd 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.

In short, 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 it.)

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 do 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)) 

Can I compile my script to a standalone executable?

Tools like App::InstallerMaker::WiX allow you to create an installer that will package the compiler and your script. However, the currently available compilers do not support creating a standalone executable yet.

If you wish to help out, the Rakudo compiler on MoarVM backend has https://github.com/MoarVM/MoarVM/issues/875 Issue opened as a place to discuss this problem.

Perl 6 distribution

When will the next version of Rakudo Star be released?

A Rakudo Star release is typically produced quarterly, with release announcements posted on rakudo.org.

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 of them.

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, that is, if Perl 6 features are used to its full extent; 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!


# 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'); 
 for my $i (1..1_000_000) { 
     my $obj = Foo->new; 
 # 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; 

You might want to use this program for comparing performance, too. It works under both languages, as long as perl -Mbigint is used for invocation for Perl 5.

my ($prev, $current) = (1, 0); 
 for (0..100_000) { 
     ($prev, $current) = ($current, $prev + $current); 
 print $current; 

35 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.


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 too 
 @h{3}:exists;   # ":exists" is too, 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, as shown in the following examples:

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.


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.


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␤» 


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 the implementation details.

See also #Abstract class.


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 a historical document for reference. See also #Exegesis and #Synopsis.


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 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 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.


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.


Blocks are code object with its own lexical scope, which allows them to define variables without interfering with other in the containing block.


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.


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 balanced delimiters 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:

variable only same as
:$foo foo => $foo
:@bar bar => @bar
:%mapper mapper => %mapper
:&test test => &test

See also #Adverb.


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.


Short for "decontainerize", meaning to remove an item from its Scalar container, often to obtain a different behavior for items that have it.


See operator. It means the type of the operator result is sufficiently different from its arguments that op= makes little sense.


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.


Too complicated to apply a meta-op to. See operator.


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.


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. The name put is a bit vague, but because it's commonly used, it's easy to learn what it does. On the other hand, the name atomic-inc-fetch is rarer, and the more descriptive name helps recall its purpose better.


Often used as a boolean value. See operator. Made via the use keyword.


Include functions from a module in the current namespace.


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.


An interface is an abstract class.


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.


Internet Relay Chat. Perl 6 developers and users usually hang out on the #perl6 channel of irc.freenode.org. This channel is also populated by a host of friendly bots that allow you to interact with Perl 6 and its codebase, as well as send delayed messages and other goodies. Check the full list in the community page of perl6.org.

IRC lingo

The following terms are often used on the Perl 6 related #IRC channels:


As Late As Possible


A self-referencing pun, e.g. "Are you ignorant or apathetic?" - "I don't know, and I don't care."


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.


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.


Do What I Mean. A programming language designer motto. The opposite of a DWIM is a #WAT.


Sometimes a test will fail under some conditions, but not others; when this test passes in some test runs and fails in others, it's called flapping.


Something in a generally current document that is no longer true but which has not yet been fixed by correcting or removing it.


For Some Value Of...


Fixed That For You

gradual typing

You don't have to specify types of variables and parameters, but if you do, it helps in early determination of impossible dispatches and better optimization. See also https://en.wikipedia.org/wiki/Gradual_typing.


If I Read (or Remember) Correctly.


In My Humble Opinion.


It Would Be Nice


Low Hanging Fruit. Usually used in the context of a (relatively) simple task to be performed by a (relative) newbie.


Looks Good To Me


Less Than Awesome. Usually used in the context of an error message that is rather non-descriptive or unrelated to the actual error.


No Such Thing


Short for "optimization", usually in either the context of spesh or JIT.


Short for "problem". As in "that's not the pb".


See #Pull Request.


Perl 5


Perl 6


Real Soon Now.


Request Tracker (https://rt.perl.org/). The place where all the bugs related to #Rakudo used to live. Nowadays, the Github issue tracker of the rakudo/rakudo repository is used for that.


An alternative form of #TMTOWTDI, explicitly including the "is" from the contraction "There's".


Too Much Information.


"There's More Than One Way To Do It", the Perl motto.


"Universal Greeting Time" - i.e., it's always "morning".


Works For Me


Work In Progress




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.


Performing lexical analysis, a step which usually precedes parsing.


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

Different types of literals are described in the syntax document.


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.


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.


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 precompiled file).


Stands for "Maybe Specification". Usually refers to existing tests in the language specification. The speaker is indicating they did not check whether the test is a spectest or a propspec test; i.e. whether the test is included in a released language specification or is a new test, proposed for the next version of the spec.


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.


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.


A method that has multiple candidates going by the same name and are subject to Multi-Dispatch.


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.


An implementation of Perl 6 targeting the .NET platform. No longer actively maintained.

Not Quite Perl

See #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.


Not Yet Implemented


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.


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 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


A virtual machine designed to run Perl 6 and other dynamic languages. No longer actively maintained.


#Parrot AST.


The Perl programming language in its many forms.


A way to describe Perl as a language, considered to be improper by many in the Perl Community.


Plain Ol' Documentation, a documentation format understood by Perl 6. See here for further information.


Stands for "Proof Of Viability". To be included in the language specification, a "proof of viability" implementation of the feature must exist in at least one mostly-compliant Perl 6 compiler.


Stands for "Proposed Specification". Usually refers to existing tests in the language specification that are proposed for inclusion in the next release.

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.


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 was one of the first interpreters/compilers written for Perl 6. It was written in Haskell by Audrey Tang.


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.


Successor to #PAST ('Q' being the next letter after 'P').


Raku is an alternative name for Perl 6 language and can be used interchangeably.


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."


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. In general, reification means turning a potential element (be it an element in a lazy list that has not been computed yet or a element in a container that has not been extracted) into its actual value.


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.


Acronym for Right-Hand Side, usually refers to the right-hand side of assignment expressions such as my $bound := $rhs.


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, 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 Perl 6's object system, and are declared using the role keyword and used in class declaration via does.


(Used in regular expressions)


A value that can be used on the right-hand side of an assignment. See also #lvalue.


Stands for "Specification APpendices". The SAP includes optional tests that implementations may choose to follow, but don't necessarily have to.

Can be used as a verb. To SAP something is to place it into Specification Appendices.


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].


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.


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.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.


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.


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.


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.


#IRC screen name for #Damian Conway, writer of the original Exegeses.


#IRC screen name for #Larry Wall, creator of Perl. The name comes from the pronunciation of #TIMTOWTDI as a word.


In this context, a token is a regex that does not backtrack. In general, tokens are extracted from the source program while lexing.


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.


A data structure used to hold a POD string with embedded formatting codes. For example:

=begin pod 
 =end pod 
 say $=pod[0].contents[0].contents.perl; 

The output will be:

["", Pod::FormattingCode.new(type => "C", meta => [], config => {}, contents => ["foo"]),""] 

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 inter twine d 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, and they inherit from Mu.


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.


Stands for "Undefined Behavior". In other words, it is something that is not explicitly specified by the language specification.

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.)


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.


The opposite of a #DWIM; counter-intuitive behavior. It is said that to every DWIM there is a corresponding WAT. See also https://www.destroyallsoftware.com/talks/wat.


A character or group of blank characters, used to separate words. An example is the space character « ».


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.

36 Pod6

An easy-to-use markup language for documenting Perl modules and programs

Pod6 is an easy-to-use markup language. It can be used for writing language documentation, for documenting programs and modules, as well as for other types of document composition.

Every Pod6 document has to begin with =begin pod and end with =end pod. Everything between these two delimiters will be processed and used to generate documentation.

=begin pod 
 A very simple Pod6 document 
 =end pod 

Block structure

A Pod6 document may consist of multiple Pod6 blocks. There are four ways to define a block: delimited, paragraph, abbreviated, and declarator; the first three yield the same result but the fourth differs. You can use whichever form is most convenient for your particular documentation task.

Delimited blocks

Delimited blocks are bounded by =begin and =end markers, both of which are followed by a valid Perl 6 identifier, which is the typename of the block. Typenames that are entirely lowercase (for example: =begin head1) or entirely uppercase (for example: =begin SYNOPSIS) are reserved.

=begin head1 
 Top Level Heading 
 =end head1 

Configuration information

After the typename, the rest of the =begin marker line is treated as configuration information for the block. This information is used in different ways by different types of blocks, but is always specified using Perl6-ish option pairs. That is, any of:

Value is... Specify with... Or with... Or with...
List :key[$e1, $e2, ...] :key($e1, $e2, ...) :key<$e1 $e2 ...>
Hash :key{$k1=>$v1, $k2=>$v2}
Boolean (true) :key :key(True) :key[True]
Boolean (false) :!key :key(False) :key[False]
String :key<str> :key('str') :key("str")
Int :key(42) :key[42] :42key
Number :key(2.3) :key[2.3]

Where '$e1, $e2, ...' are list elements of type String, Int, Number, or Boolean. Lists may have mixed element types. Note that one-element lists are converted to the type of their element (String, Int, Number, or Boolean). Also note that "bigints" can be used if required.

For hashes, '$k1, $k2, ...' are keys of type Str and '$v1, $v2, ...' are values of type String, Int, Number, or Boolean.

Strings are delimited by single or double quotes. Whitespace is not significant outside of strings. Hash keys need not be quote-delimited unless they contain significant whitespace. Strings entered inside angle brackets become lists if any whitespace is used inside the angle brackets.

All option keys and values must, of course, be constants since Pod6 is a specification language, not a programming language. Specifically, option values cannot be closures. See Synopsis 2 for details of the various Perl 6 pair notations.

The configuration section may be extended over subsequent lines by starting those lines with an = in the first (virtual) column followed by a whitespace character.

This feature is not yet completely implemented. All configuration information currently must be provided on the same line as the =begin marker line or =for name for paragraph blocks.

Paragraph blocks

Paragraph blocks begin by a =for marker and end by the next Pod6 directive or the first blank line. The =for marker is followed by the typename of the block plus, optionally, any configuration data as in the delimited blocks described above.

=for head1 
 Top Level Heading 

Abbreviated blocks

Abbreviated blocks begin by an '=' sign, which is followed immediately by the typename of the block. All following data are part of the contents of the block, thus configuration data cannot be specified for an abbreviated block. The block ends at the next Pod6 directive or the first blank line.

=head1 Top level heading 

Declarator blocks

Declarator blocks differ from the others by not having a specific type, instead they are attached to some source code.

Declarator blocks are introduced by a special comment: either #| or #=, which must be immediately followed by either a space or an opening curly brace. If followed by a space, the block is terminated by the end of line; if followed by one or more opening curly braces, the block is terminated by the matching sequence of closing curly braces.

Blocks starting with #| are attached to the code after them, and blocks starting with #= are attached to the code before them.

Since declarator blocks are attached to source code, they can be used to document classes, roles, subroutines and in general any statement or block.

The WHY method can be used on these classes, roles, subroutines etc. to return the attached Pod6 value.

#| Base class for magicians 
 class Magician { 
   has Int $.level; 
   has Str @.spells; 
 #| Fight mechanics 
 sub duel(Magician $a, Magician $b) { 
 #= Magicians only, no mortals. 
 say Magician.WHY; # OUTPUT: «Base class for magicians␤» 
 say &duel.WHY.leading; # OUTPUT: «Fight mechanics␤» 
 say &duel.WHY.trailing; # OUTPUT: «Magicians only, no mortals.␤» 

These declarations can extend multiple blocks:

#|( This is an example of stringification: 
     * Numbers turn into strings 
     * Regexes operate on said strings 
     * C<with> topicalizes and places result into $_ 
 sub search-in-seq( Int $end, Int $number ) { 
     with (^$end).grep( /^$number/ ) { 
         .say for $_<>; 
 #=« Uses 
     * topic 
     * decont operator 

By using a matched pair of parenthesis constructs such as () or «» the comments can extend multiple lines. This format, however, will not translate to a multi-line display by perl6 -doc.

Block types

Pod6 offers a wide range of standard block types.


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

=head1 A top level heading 
 =head2 A second level heading 
 =head3 A third level heading 

Ordinary paragraphs

An ordinary paragraph consists of text that is to be formatted into a document at the current level of nesting, with whitespace squeezed, lines filled, and any special inline mark-up applied.

Ordinary paragraphs consist of one or more consecutive lines of text, each of which starts with a non-whitespace character. The paragraph is terminated by the first blank line or block directive.

For example:

=head1 This is a heading block 
 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. It is terminated by 
 the first blank line. 
 This is another ordinary paragraph. 
 Its     text    will  also be squeezed and 
 short lines filled. It is terminated by 
 the trailing directive on the next line. 
 =head2 This is another heading block 
 This is yet another ordinary paragraph, 
 at the first virtual column set by the 
 previous directive 

Ordinary paragraphs do not require an explicit marker or delimiters.

Alternatively, there is also an explicit =para marker that can be used to explicitly mark a paragraph.

 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. 

In addition, the longer =begin para and =end para form can be used.

For example:

=begin para 
 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. 
 This is still part of the same paragraph, 
 which continues until an... 
 =end para 

As demonstrated by the previous example, within a delimited =begin para and =end para block, any blank lines are preserved.

Code blocks

Code blocks are used to specify source code, which should be rendered without re-justification, without whitespace-squeezing, and without recognizing any inline formatting codes. Typically these blocks are used to show examples of code, mark-up, or other textual specifications, and are rendered using a fixed-width font.

A code block may be implicitly specified as one or more lines of text, each of which starts with a whitespace character. The implicit code block is then terminated by a blank line.

For example:

This ordinary paragraph introduces a code block: 
     my $name = 'John Doe'; 
     say $name; 

Code blocks can also be explicitly defined by enclosing them in =begin code and =end code

    =begin code 
     my $name = 'John Doe'; 
     say $name; 
     =end code 

I/O blocks

Pod6 provides blocks for specifying the input and output of programs.

The =input block is used to specify pre-formatted keyboard input, which should be rendered without re-justification or squeezing of whitespace.

The =output block is used to specify pre-formatted terminal or file output, which should also be rendered without re-justification or whitespace-squeezing.


Unordered lists

Lists in Pod6 are specified as a series of =item blocks.

For example:

The three suspects are: 
 =item  Happy 
 =item  Sleepy 
 =item  Grumpy 

The three suspects are:

Definition lists

Lists that define terms or commands use =defn, equivalent to the DL lists in HTML

=defn Happy 
 When you're not blue. 
 =defn Blue 
 When you're not happy. 

will be rendered as


When you're not blue.


When you're not happy.

Multi-level lists

Lists may be multi-level, with items at each level specified using the =item1, =item2, =item3, etc. blocks.

Note that =item is just an abbreviation for =item1.

For example:

=item1  Animal 
 =item2     Vertebrate 
 =item2     Invertebrate 
 =item1  Phase 
 =item2     Solid 
 =item2     Liquid 
 =item2     Gas 

Multi-paragraph lists

Using the delimited form of the =item block (=begin item and =end item), we can specify items that contain multiple paragraphs.

For example:

Let's consider two common proverbs: 
 =begin item 
 I<The rain in Spain falls mainly on the plain.> 
 This is a common myth and an unconscionable slur on the Spanish 
 people, the majority of whom are extremely attractive. 
 =end item 
 =begin item 
 I<The early bird gets the worm.> 
 In deciding whether to become an early riser, it is worth 
 considering whether you would actually enjoy annelids 
 for breakfast. 
 =end item 
 As you can see, folk wisdom is often of dubious value. 

Let's consider two common proverbs:

As you can see, folk wisdom is often of dubious value.


Check out this page for documentation related to Tables

Pod6 comments

Pod6 comments are comments that Pod6 renderers ignore.

Comments are useful for meta-documentation (documenting the documentation). Single-line comments use the =comment marker:

=comment Add more here about the algorithm 

For multi-line comments, use a delimited comment block:

=begin comment 
 This comment is 
 =end comment 

Semantic blocks

All uppercase block typenames are reserved for specifying standard documentation, publishing, source components, or meta-information.


Formatting codes

Formatting codes provide a way to add inline mark-up to a piece of text.

All Pod6 formatting codes consist of a single capital letter followed immediately by a set of single or double angle brackets; Unicode double angle brackets may be used.

Formatting codes may nest other formatting codes.

The following codes are available: B, C, E, I, K, L, N, P, R, T, U, V, X, and Z.


To format a text in bold enclose it in B< >

Perl 6 is B<awesome> 

Perl 6 is awesome


To format a text in italic enclose it in I< >

Perl 6 is I<awesome> 

Perl 6 is awesome


To underline a text enclose it in U< >

Perl 6 is U<awesome> 


To flag text as code and treat it verbatim enclose it in C< >

C<my $var = 1; say $var;> 

my $var = 1; say $var;

To create a link enclose it in L< >

A vertical bar (optional) separates label and target.

The target location can be an URL (first example) or a local Pod6 document (second example). Local file names are relative to the base of the project, not the current document.

Perl 6 homepage L<https://perl6.org> 
 L<Perl 6 homepage|https://perl6.org> 

Perl 6 homepage https://perl6.org

Perl 6 homepage

Structure L</language/about#Structure|/language/about#Structure> 

Structure /language/about#Structure


To create a link to a section in the same document:

Comments L<#Comments> 

Comments #Comments


This code is not implemented in Pod::To::HTML, but is partially implemented in Pod::To::BigPage.

A second kind of link — the P<> or placement link — works in the opposite direction. Instead of directing focus out to another document, it allows you to assimilate the contents of another document into your own.

In other words, the P<> formatting code takes a URI and (where possible) inserts the contents of the corresponding document inline in place of the code itself.

P<> codes are handy for breaking out standard elements of your documentation set into reusable components that can then be incorporated directly into multiple documents. For example:


might produce:


This document is copyright (c) MegaGigaTeraPetaCorp, 2006. All rights reserved.



If a renderer cannot find or access the external data source for a placement link, it must issue a warning and render the URI directly in some form, possibly as an outwards link. For example:


See: file:/shared/docs/std_copyright.pod


See: http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt

You can use any of the following URI forms (see #Links) in a placement link.


A comment is text that is never rendered.

To create a comment enclose it in Z< >

Perl 6 is awesome Z<Of course it is!> 

Perl 6 is awesome


Notes are rendered as footnotes.

To create a note enclose it in N< >

Perl 6 is multi-paradigmatic N<Supporting Procedural, Object Oriented, and Functional programming> 

Keyboard input

To flag text as keyboard input enclose it in K< >

Enter your name K<John Doe> 


The R<> formatting code specifies that the contained text is a replaceable item, a placeholder, or a metasyntactic variable. It is used to indicate a component of a syntax or specification that should eventually be replaced by an actual value. For example:

The basic ln command is: ln source_file target_file


Then enter your details at the prompt: 
 =for input 
     Name:  your surname 
       ID:  your employee number 
     Pass:  your 36-letter password 

Terminal output

To flag text as terminal output enclose it in T< >

Hello T<John Doe> 


To include Unicode code points or HTML5 character references in a Pod6 document, enclose them in E< >

E< > can enclose a number, which is treated as the decimal Unicode value for the desired code point. It can also enclose explicit binary, octal, decimal, or hexadecimal numbers using the Perl 6 notations for explicitly based numbers.

Perl 6 makes considerable use of the E<171> and E<187> characters. 
 Perl 6 makes considerable use of the E<laquo> and E<raquo> characters. 
 Perl 6 makes considerable use of the E<0b10101011> and E<0b10111011> characters. 
 Perl 6 makes considerable use of the E<0o253> and E<0o273> characters. 
 Perl 6 makes considerable use of the E<0d171> and E<0d187> characters. 
 Perl 6 makes considerable use of the E<0xAB> and E<0xBB> characters. 

Perl 6 makes considerable use of the « and » characters.

Verbatim text

This code is not implemented by Pod::To::HTML, but is implemented in Pod::To::BigPage.

The V<> formatting code treats its entire contents as being verbatim, disregarding every apparent formatting code within it. For example:

The B<V< V<> >> formatting code disarms other codes 
 such as V< I<>, C<>, B<>, and M<> >. 

Note, however that the V<> code only changes the way its contents are parsed, not the way they are rendered. That is, the contents are still wrapped and formatted like plain text, and the effects of any formatting codes surrounding the V<> code are still applied to its contents. For example the previous example is rendered as:

The V<> formatting code disarms other codes such as I<>, C<>, B<>, and M<> .

Indexing terms

Anything enclosed in an X<> code is an index entry. The contents of the code are both formatted into the document and used as the (case-insensitive) index entry:

An  X<array>  is an ordered list of scalars indexed by number, 
 starting with 0. A  X<hash>  is an unordered collection of scalar 
 values indexed by their associated string key. 

You can specify an index entry in which the indexed text and the index entry are different, by separating the two with a vertical bar:

An  X<array|arrays>  is an ordered list of scalars indexed by number, 
 starting with 0. A  X<hash|hashes>  is an unordered collection of 
 scalar values indexed by their associated string key. 

In the two-part form, the index entry comes after the bar and is case-sensitive.

You can specify hierarchical index entries by separating indexing levels with commas:

An X<array| arrays, definition of > is an ordered list of scalars 
 indexed by number, starting with 0. A X<hash| hashes, definition of > 
 is an unordered collection of scalar values indexed by their 
 associated string key. 

You can specify two or more entries for a single indexed text, by separating the entries with semicolons:

A X<hash| hashes, definition of; associative arrays > 
 is an unordered collection of scalar values indexed by their 
 associated string key. 

The indexed text can be empty, creating a "zero-width" index entry:

X<|puns, deliberate> This is called the "Orcish Maneuver" 
 because you "OR" the "cache". 

Rendering Pod


In order to generate HTML from Pod, you need the Pod::To::HTML module.

If it is not already installed, install it by running the following command: zef install Pod::To::HTML

Once installed, run the following command in the terminal:

perl6 --doc=HTML input.pod6 > output.html 


In order to generate Markdown from Pod, you need the Pod::To::Markdown module.

If it is not already installed, install it by running the following command: zef install Pod::To::Markdown

Once installed, run the following command in the terminal:

perl6 --doc=Markdown input.pod6 > output.md 


In order to generate Text from Pod, you can use the default Pod::To::Text module.

Using the terminal, run the following command:

perl6 --doc=Text input.pod6 > output.txt 

You can omit the =Text portion:

perl6 --doc input.pod6 > output.txt 

You can even embed Pod6 directly in your program and add the traditional Unix command line "--man" option to your program with a multi MAIN subroutine like this:

multi MAIN(Bool :$man) { 
     run $*EXECUTABLE, '--doc', $*PROGRAM; 

Now myprogram --man will output your Pod6 rendered as a man page.

Accessing Pod

In order to access Pod6 documentation from within a Perl 6 program the special = twigil, as documented in the variables section, must be used.

The = twigil provides the introspection over the Pod6 structure, providing a Pod::Block tree root from which it is possible to access the whole structure of the Pod6 document.

As an example, the following piece of code introspects its own Pod6 documentation:

=begin pod 
 =head1 This is a head1 title 
 This is a paragraph. 
 =head2 Subsection 
 Here some text for the subsection. 
 =end pod 
 for $=pod -> $pod-item { 
     for $pod-item.contents -> $pod-block { 

producing the following output:

Pod::Heading.new(level => 1, config => {}, contents => [Pod::Block::Para.new(config => {}, contents => ["This is a head1 title"])]); 
 Pod::Block::Para.new(config => {}, contents => ["This is a paragraph."]); 
 Pod::Heading.new(level => 2, config => {}, contents => [Pod::Block::Para.new(config => {}, contents => ["Subsection"])]); 
 Pod::Block::Para.new(config => {}, contents => ["Here some text for the subsection."]); 

37 Pod 6 tables

The good, the bad and the ugly

The official specification for Perl 6 POD tables is located in the Documentation specification here: Tables. Although Pod 6 specifications are not completely handled properly yet, several projects are ongoing to correct the situation; one such project is ensuring the proper handling of Pod 6 tables.

As part of that effort, this document explains the current state of Pod 6 tables by example: valid tables, invalid tables, and ugly tables (i.e., valid tables that, because of sloppy construction, may result in something different than the user expects).


1. The only valid column separators are either visible (' | ' or ' + ') (note at least one space is required before and after the visible column separators) or invisible [two or more contiguous whitespace (WS) characters (e.g., '  ')]. Column separators are not normally recognized as such at the left or right side of a table, but one on the right side may result in one or more empty cells depending upon the number of the cells in other rows. (Note that a pipe or plus character meant as part of cell data will result in an unintended extra column unless the character is escaped with a backslash, e.g., '\|' or '\+'.)

2. Mixing visible and invisible column separators in the same table is illegal.

3. The only valid row separator characters are '_', '-', '+', ' ', '|', and '='.

4. Consecutive interior row-separator lines are illegal.

5. Leading and trailing row-separator lines generate a warning.

6. Formatting blocks in table cells currently are ignored and treated as plain text.

HINT: During development, use of the environment variable RAKUDO_POD6_TABLE_DEBUG will show you how Rakudo interprets your pod tables before they are passed to renderers such as Pod::To::HTML, Pod::To::Text, and Pod::To::Markdown.

Best practices

HINT: Not adhering to the following best practices may require more table processing due to additional looping over table rows.

1. Use of WS for column separators is fragile, and they should only be used for simple tables. The Ugly Tables section below illustrates the problem.

2. Align table columns and rows carefully. See the examples in later best practices.

3. Don't use visual borders on the table.

4. For tables with a heading and single- or multi-line content, use one or more contiguous equal signs ('=') as the row separator after the heading, and use one or more contiguous hyphens ('-') as the row separator in the content portion of the table. For example,

=begin table 
  hdr col 0 | hdr col 1 
  row 0     | row 0 
  col 0     | col 1 
  row 1     | row 1 
  col 0     | col 1 
 =end table 
=begin table 
  hdr col 0   | hdr col 1 
  row 0 col 0 | row 0 col 1 
  row 1 col 0 | row 1 col 1 
 =end table 

5. For tables with no header and multi-line content, use one or more contiguous hyphens ('-') as the row separator in the content portion of the table. For example,

=begin table 
  row 0       | row 0 
  col 0       | col 1 
  row 1 col 0 | row 1 col 1 
 =end table 

6. For tables with many rows and no multi-line content, using no row separators is fine. However, with one or more rows with multi-line content, it is easier to ensure proper results by using a row separator line (visible or invisible) between every content row.

7. Ensure intentionally empty cells have column separators, otherwise expect a warning about short rows being filled with empty cells. (Tables rows will always have the same number of cells as the row with the most cells. Short rows are padded on the right with empty cells and generate a warning.)

8. Adding a caption to a table is possible using the =begin table line as in this example:

=begin table :caption<My Tasks> 
 mow lawn 
 take out trash 
 =end table 

Although not a good practice, currently there is in use an alternate method of defining a caption as shown in this example:

=begin table :config{caption => "My Tasks"} 
 mow lawn 
 take out trash 
 =end table 

Note the alternative method of putting the caption in the config hash was necessary before the :caption method was implemented, but that method is now considered to be deprecated. The practice will generate a warning in the upcoming version 6.d, and it will raise an exception in version 6.e.

Good tables

Following are examples of valid (Good) tables (taken from the current Specification Tests).

=begin table 
         The Shoveller   Eddie Stevens     King Arthur's singing shovel 
         Blue Raja       Geoffrey Smith    Master of cutlery 
         Mr Furious      Roy Orson         Ticking time bomb of fury 
         The Bowler      Carol Pinnsler    Haunted bowling ball 
 =end table 
     Constants           1 
     Variables           10 
     Subroutines         33 
     Everything else     57 
=for table 
     mouse    | mice 
     horse    | horses 
     elephant | elephants 
     Animal | Legs |    Eats 
     Zebra  +   4  + Cookies 
     Human  +   2  +   Pizza 
     Shark  +   0  +    Fish 
         Superhero     | Secret          | 
                       | Identity        | Superpower 
         The Shoveller | Eddie Stevens   | King Arthur's singing shovel 
=begin table 
         Superhero       Identity          Superpower 
         =============   ===============   =================== 
         The Shoveller   Eddie Stevens     King Arthur's 
                                           singing shovel 
         Blue Raja       Geoffrey Smith    Master of cutlery 
         Mr Furious      Roy Orson         Ticking time bomb 
                                           of fury 
         The Bowler      Carol Pinnsler    Haunted bowling ball 
 =end table 
     X | O | 
       | X | O 
       |   | X 
     X   O 
         X   O 
=begin table 
 =end table 

Bad tables

Following are examples of invalid (Bad) tables, and they should trigger an unhandled exception during parsing.

=begin table 
 r0c0 +  r0c1 | r0c3 
 =end table 
=begin table 
 r0c0 +  r0c1 | r0c3 
 r1c0    r0c1   r0c3 
 =end table 
=begin table 
 r0c0 |  r0c1 
 r1c0 |  r1c1 
 =end table 

Ugly tables

Following are examples of valid tables that are probably intended to be two columns, but the columns are not aligned well so each will parse as a single-column table.

Notice the second row has the two words separated by only one WS character, while it takes at least two adjacent WS characters to define a column separation. This is a valid table but will be parsed as a single-column table.

=begin table 
 r0c0    r0c1 
  r1c0 r0c1 
 =end table 

Notice the second row has the two words separated by a visible character ('|') but the character is not recognized as a column separator because it doesn't have an adjacent WS character on both sides of it. Although this is a legal table, the result will not be what the user intended because the first row has two columns while the second row has only one column, and it will thus have an empty second column.

=begin table 
 r0c0  |  r0c1 
  r1c0 |r0c1 
 =end table 

38 Terms

Perl 6 terms

Most syntactic constructs in Perl 6 can be categorized in terms and operators.

Here you can find an overview of different kinds of terms.




Int literals consist of digits and can contain underscores between any two digits.

To specify a base other than ten, use the colonpair form :radix<number> .



Rat literals (rational numbers) contain two integer parts joined by a dot.

Note that trailing dots are not allowed, so you have to write 1.0 instead of 1. (this rule is important because there are infix operators starting with a dot, for example the .. Range operator).



Num literals (floating point numbers) consist of Rat or Int literals followed by an e and a (possibly negative) exponent. 3e8 constructs a Num with value 3 * 10**8.


'a string' 
 'I\'m escaped!' 
 "I don't need to be" 
 "\"But I still can be,\" he said." 
 q|Other delimiters can be used too!| 

String literals are most often created with ' or ", however strings are actually a powerful sub-language of Perl 6. See Quoting Constructs.


/ match some text / 
 rx/slurp \s rest (.*) $/ 

These forms produce regex literals. See quoting constructs.


a => 1 
 'a' => 'b' 
 :identifier<value1 value2> 
 :identifier['val1', 'val2'] 
 :identifier{key1 => 'val1', key2 => 'value2'} 

Pair objects can be created either with infix:«=>» (which auto-quotes the left-hand side if it is an identifier), or with the various colon-pair forms. Those almost always start with a colon and then are followed either by an identifier or the name of an already existing variable (whose name without the sigil is used as the key and value of the variable is used as the value of the pair). There is a special form where an integer value is immediately after the colon and the key is immediately after the value.

In the identifier form of a colon-pair, the optional value can be any circumfix. If it is left blank, the value is Bool::True. The value of the :!identifier form is Bool::False.

If used in an argument list, all of these forms count as named arguments, with the exception of 'quoted string' => $value .


 1, 2, 3 
 <a b c> 
 «a b c» 
 qw/a b c/ 

List literals are: the empty pair of parentheses (), a comma-separated list, or several quoting constructs.

term *

Creates an object of type Whatever. See Whatever documentation for more details.

Identifier terms

There are built-in identifier terms in Perl 6, which are listed below. In addition one can add new identifier terms with the syntax:

sub term:<forty-two> { 42 };
say forty-two

or as constants:

constant forty-two = 42;
say forty-two;

term self

Inside a method, self refers to the invocant (i.e. the object the method was called on). If used in a context where it doesn't make sense, a compile-time exception of type X::Syntax::NoSelf is thrown.

term now

Returns an Instant object representing the current time. It includes leap seconds and as such a few dozen seconds larger than time:

say (now - time).Int; # OUTPUT: «37␤»

term time

Returns the current POSIX time as an Int. See now for high-resolution timestamp that includes leap seconds.

term rand

Returns a pseudo-random Num in the range 0..^1.

term π

Returns the number π at codepoint U+03C0 (GREEK SMALL LETTER PI), i.e. the ratio between circumference and diameter of a circle. The ASCII equivalent of π is pi.

term pi

Returns the number π, i.e., the ratio between circumference and diameter of a circle. pi is the ASCII equivalent of π.

term τ

Returns the number τ at codepoint U+03C4 (GREEK SMALL LETTER TAU), i.e. the ratio between circumference and radius of a circle. The ASCII equivalent of τ is tau.

term tau

Returns the number τ, i.e. the ratio between circumference and radius of a circle. tau is the ASCII equivalent of τ.

term 𝑒

Returns Euler's number at codepoint U+1D452 (MATHEMATICAL ITALIC SMALL E). The ASCII equivalent of 𝑒 is e.

term e

Returns Euler's number. e is the ASCII equivalent of 𝑒.

term i

Returns the imaginary unit (for Complex numbers).

term ∅

Returns set(), aka the empty set, at codepoint U+2205 (EMPTY SET).


Variables are discussed in the variable language docs.


Constants are similar to variables without a container, and thus cannot be rebound. However, their initializers are evaluated at BEGIN time:

constant speed-of-light = 299792458; # m/s
constant @foo  = 1, 2, 3;
constant &talk = &say;
talk speed-of-light²; # OUTPUT: «89875517873681764␤»
talk @foo;            # OUTPUT: «(1 2 3)␤»

Compile-time evaluation means you should be careful with using constants inside modules, which get automatically precompiled, and so the value of the constant would not change even between multiple executions of the program:

# Foo.pm6 
 unit module Foo; 
 constant comp-time = DateTime.now; 
# The value of the constant remains the same even though our script 
 # is executed multiple times: 
 $ perl6 -I. -MFoo -e 'say Foo::comp-time' 
 $ perl6 -I. -MFoo -e 'say Foo::comp-time' 

Constants are declared with keyword constant followed by an identifier with an optional sigil. Constants are our scoped by default.

    constant foo  = 42; 
 my  constant $baz = rand; 
 our constant @foo = 1, 2, 3; 
     constant %bar = %(:42foo, :100bar); 

NOTE: if you're using the Rakudo compiler, you need version 2018.08 or newer for type constraints and auto-coercion on constants to be available. Auto-coercion on %-sigiled constants requires 6.d

An optional type constraint can be used, in which case the use of scope declarator is required:

# !!WRONG!! missing scope declarator before type: 
 Int constant bar = 42; 
 # RIGHT: 
 our Int constant bar = 42; 

Unlike variables, you cannot parameterize @-, %-, and &-sigiled constants by specifying the parameterization type in the declarator itself:

# !!WRONG!! cannot parameterize @-sigiled constant with Int 
 our Int constant @foo = 42; 
 # OK: parameterized types as values are fine 
 constant @foo = Array[Int].new: 42; 

The reason for the restriction is that constants with @ and % sigils default to List and Map types, which cannot be parameterized. To keep things simple and consistent, parameterization was simply disallowed in these constructs.

The @-, %-, and &-sigiled constants specify implied typecheck of the given value for Positional, Associative, and Callable roles respectively. The @-sigiled constants—and as of 6.d language version, the %-sigiled constants as well—perform auto-coercion of the value if it does not pass the implied typecheck. The @-sigiled constants will coerce using method cache and %-sigiled constants coerce using method Map.

constant @foo = 42; 
 @foo.perl.say; # OUTPUT: «(42,)» 
 constant @bar = [<a b c>]; 
 @bar.perl.say; # OUTPUT: «["a", "b", "c"]» 
use v6.d.PREVIEW; 
 constant %foo = <foo bar>; 
 %foo.perl.say; # OUTPUT: «Map.new((:foo("bar")))» 
 constant %bar = {:10foo, :72bar}; 
 %bar.perl.say; # OUTPUT: «{:bar(72), :foo(10)}» 
 # Pair is already Associative, so it remains a Pair 
 constant %baz = :72baz; 
 %baz.perl.say; # OUTPUT: «:baz(72)» 

For convenience and consistency reasons, you can use the binding operator ( := ) instead of the assignment operator, use backslash before sigilless name of the constant variable (same as with sigilless variables), and even omit the name of the constant entirely to have an anonymous constant. Since you can't refer to anonymous entities, you may be better off using a BEGIN phaser instead, for clarity.

constant %foo := :{:42foo};
constant \foo = 42;
constant = 'anon';

39 Testing

Writing and running tests in Perl 6

Testing code is an integral part of software development. Tests provide automated, repeatable verifications of code behavior, and ensures your code works as expected.

In Perl 6, the Test module provides a testing framework, used also by Perl 6's official spectest suite.

The testing functions emit output conforming to the Test Anything Protocol. In general, they are used in sink context:

ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" 

but all functions also return as a Boolean if the test has been successful or not, which can be used to print a message if the test fails:

ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" \ 
   or diag "\nTo use hyphen in name, pass :relaxed-name to meta-ok\n"; 

Writing tests

As with any Perl project, the tests live under the t directory in the project's base directory.

A typical test file looks something like this:

use Test;      # a Standard module included with Rakudo 
 use lib 'lib'; 
 plan $num-tests; 
 # .... tests 
 done-testing;  # optional with 'plan' 

We ensure that we're using Perl 6, via the use v6.c pragma, then we load the Test module and specify where our libraries are. We then specify how many tests we plan to run (such that the testing framework can tell us if more or fewer tests were run than we expected) and when finished with the tests, we use done-testing to tell the framework we are done.

Thread safety

Note that routines in Test module are not thread-safe. This means you should not attempt to use the testing routines in multiple threads simultaneously, as the TAP output might come out of order and confuse the program interpreting it.

There are no current plans to make it thread safe. If threaded-testing is crucial to you, you may find some suitable ecosystem modules to use instead of Test for your testing needs.

Running tests

Tests can be run individually by specifying the test filename on the command line:

$ perl6 t/test-filename.t 

To run all tests in the directory recursively, prove6 application can be used.

You have to install it before using with zef:

$ zef install App::Prove6 

You can run prove6 in a distribution directory this way:

$ prove6 --lib t/ 

The t/ argument specified directory that contains tests and the --lib option is passed to include lib directory into Perl 6 distribution path, it is an equivalent of -Ilib argument of perl6 command.

For more documentation regarding prove6 usage refer to its page.

To abort the test suite upon first failure, set the PERL6_TEST_DIE_ON_FAIL environmental variable:

$ PERL6_TEST_DIE_ON_FAIL=1 perl6 t/test-filename.t 

The same variable can be used within the test file. Set it before loading the Test module:

use Test;

Test plans

Tests plans use plan for declaring how many plans are going to be done or, as might be the case, skipped. If no plan is declared, done-testing is used to declare the end of the tests.

Testing return values

The Test module exports various functions that check the return value of a given expression and produce standardized test output.

In practice, the expression will often be a call to a function or method that you want to unit-test. ok and nok will match True and False. However, where possible it's better to use one of the specialized comparison test functions below, because they can print more helpful diagnostics output in case the comparison fails.

By string comparison

is and nok test for equality using the proper operator, depending on the object (or class) it's handled.

By approximate numeric comparison

is-approx compares numbers with a certain precision, which can be absolute or relative. It can be useful for numeric values whose precision will depend on the internal representation.

By structural comparison

Structures can be also compared using is-deeply, which will check that internal structures of the objects compared is the same.

By arbitrary comparison

You can use any kind of comparison with cmp-ok, which takes as an argument the function or operator that you want to be used for comparing.

By object type

isa-ok tests whether an object is of a certain type.

By method name

can-ok is used on objects to check whether they have that particular method.

By role

does-ok checks whether the given variable can do a certain Role.

By regex

like and unlike check using regular expressions; in the first case passes if a match exists, in the second case when it does not.

Testing modules

Modules are tentatively loaded with use-ok, which fails if they fail to load.

Testing exceptions

dies-ok and lives-ok are opposites ways of testing code; the first checks that it throws an exception, the second that it does not; throws-like checks that the code throws the specific exception it gets handed as an argument; fails-like, similarly, checks if the code returns a specific type of Failure. eval-dies-ok and eval-lives-ok work similarly on strings that are evaluated prior to testing.

Grouping tests

The result of a group of subtests is only ok if all subtests are ok; they are grouped using subtest.

Skipping tests

Sometimes tests just aren't ready to be run, for instance a feature might not yet be implemented, in which case tests can be marked as todo. Or it could be the case that a given feature only works on a particular platform - in which case one would skip the test on other platforms; skip-rest will skip the remaining tests instead of a particular number given as argument; bail-out will simply exit the tests with a message.

Manual control

If the convenience functionality documented above does not suit your needs, you can use the following functions to manually direct the test harness output; pass will say a test has passed, and diag will print a (possibly) informative message.

40 Traps to avoid

Traps to avoid when getting started with Perl 6

When learning a programming language, possibly with the background of being familiar with another programming language, there are always some things that can surprise you and might cost valuable time in debugging and discovery.

This document aims to show common misconceptions in order to avoid them.

During the making of Perl 6 great pains were taken to get rid of warts in the syntax. When you whack one wart, though, sometimes another pops up. So a lot of time was spent finding the minimum number of warts or trying to put them where they would rarely be seen. Because of this, Perl 6's warts are in different places than you may expect them to be when coming from another language.

Variables and constants

Constants are computed at compile time

Constants are computed at compile time, so if you use them in modules keep in mind that their values will be frozen due to precompilation of the module itself:

# WRONG (most likely): 
 unit module Something::Or::Other; 
 constant $config-file = "config.txt".IO.slurp; 

The $config-file will be slurped during precompilation and changes to config.txt file won't be re-loaded when you start the script again; only when the module is re-compiled.

Avoid using a container and prefer binding a value to a variable that offers a behavior similar to a constant, but allowing the value to get updated:

# Good; file gets updated from 'config.txt' file on each script run: 
 unit module Something::Or::Other; 
 my $config-file := "config.txt".IO.slurp; 

Assigning to Nil produces a different value, usually Any

Actually, assigning to Nil reverts the variable to its default value. So:

my @a = 4, 8, 15, 16; 
 @a[2] = Nil; 
 say @a; # OUTPUT: «[4 8 (Any) 16]␤» 

In this case, Any is the default value of an Array element.

You can purposefully assign Nil as a default value:

my %h is default(Nil) = a => Nil; 
 say %h; # OUTPUT: «Hash %h = {:a(Nil)}␤» 

Or bind a value to Nil if that is the result you want:

@a[3] := Nil; 
 say @a; # OUTPUT: «[4 8 (Any) Nil]␤» 

This trap might be hidden in the result of functions, such as matches:

my $result2 = 'abcdef' ~~ / dex /; 
 say "Result2 is { $result2.^name }"; # OUTPUT: «Result2 is Any␤» 

A Match will be Nil if it finds nothing; however it assigning Nil to $result2 above will result in its default value, which is Any as shown.

Using a block to interpolate anon state vars

The programmer intended for the code to count the number of times the routine is called, but the counter is not increasing:

sub count-it { say "Count is {$++}" } 
 # Count is 0 
 # Count is 0 

When it comes to state variables, the block in which the vars are declared gets cloned —and vars get initialized anew— whenever that block's block is re-entered. This lets constructs like the one below behave appropriately; the state variable inside the loop gets initialized anew each time the sub is called:

sub count-it { 
     for ^3 { 
         state $count = 0; 
         say "Count is $count"; 
 say "…and again…"; 
 # Count is 0 
 # Count is 1 
 # Count is 2 
 # …and again… 
 # Count is 0 
 # Count is 1 
 # Count is 2 

The same layout exists in our buggy program. The { } inside a double-quoted string isn't merely an interpolation to execute a piece of code. It's actually its own block, which is just as in the example above gets cloned each time the sub is entered, re-initializing our state variable. To get the right count, we need to get rid of that inner block, using a scalar contextualizer to interpolate our piece of code instead:

sub count-it { say "Count is $($++)" } 
 # Count is 0 
 # Count is 1 

Alternatively, you can also use the concatenation operator instead:

sub count-it { say "Count is " ~ $++ } 

Using set subroutines on Associative when the value is falsy

Using (cont), , , (elem), , or on classes implementing Associative will return False if the value of the key is falsy:

enum Foo «a b»; 
 say Foo.enums ∋ 'a'; 
 # False 

Instead, use :exists:

enum Foo «a b»; 
 say Foo.enums<a>:exists; 
 # True 


Beware of empty "blocks"

Curly braces are used to declare blocks. However, empty curly braces will declare a hash.

$ = {say 42;} # Block 
 $ = {;}       # Block 
 $ = {…}       # Block 
 $ = { }       # Hash 

You can use the second form if you effectively want to declare an empty block:

my &does-nothing = {;};
say does-nothing(33); # OUTPUT: «Nil␤»


Assigning to attributes

Newcomers often think that, because attributes with accessors are declared as has $.x, they can assign to $.x inside the class. That's not the case.

For example

class Point { 
     has $.x; 
     has $.y; 
     method double { 
         $.x *= 2;   # WRONG 
         $.y *= 2;   # WRONG 
 say Point.new(x => 1, y => -2).double.x 
 # OUTPUT: «Cannot assign to an immutable value␤» 

the first line inside the method double is marked with # WRONG because $.x, short for $( self.x ), is a call to a read-only accessor.

The syntax has $.x is short for something like has $!x; method x() { $!x }, so the actual attribute is called $!x, and a read-only accessor method is automatically generated.

Thus the correct way to write the method double is

method double { 
     $!x *= 2; 
     $!y *= 2; 

which operates on the attributes directly.

BUILD prevents automatic attribute initialization from constructor arguments

When you define your own BUILD submethod, you must take care of initializing all attributes by yourself. For example

class A { 
     has $.x; 
     has $.y; 
     submethod BUILD { 
         $!y = 18; 
 say A.new(x => 42).x;       # OUTPUT: «Any␤» 

leaves $!x uninitialized, because the custom BUILD doesn't initialize it.

Note: Consider using TWEAK instead. Rakudo supports TWEAK method since release 2016.11.

One possible remedy is to explicitly initialize the attribute in BUILD:

submethod BUILD(:$x) { 
     $!y = 18; 
     $!x := $x; 

which can be shortened to:

submethod BUILD(:$!x) { 
     $!y = 18; 


Whitespace in regexes does not match literally

say 'a b' ~~ /a b/; # OUTPUT: «False␤» 

Whitespace in regexes is, by default, considered an optional filler without semantics, just like in the rest of the Perl 6 language.

Ways to match whitespace:

Ambiguities in parsing

While some languages will let you get away with removing as much whitespace between tokens as possible, Perl 6 is less forgiving. The overarching mantra is we discourage code golf, so don't scrimp on whitespace (the more serious underlying reason behind these restrictions is single-pass parsing and ability to parse Perl 6 programs with virtually no backtracking).

The common areas you should watch out for are:

Block vs. Hash slice ambiguity

# WRONG; trying to hash-slice a Bool: 
 while ($++ > 5){ .say } 
 while ($++ > 5) { .say } 
 # EVEN BETTER; Perl 6 does not require parentheses there: 
 while $++ > 5 { .say } 

Reduction vs. Array constructor ambiguity

# WRONG; ambiguity with `[<]` meta op: 
 my @a = [[<foo>],]; 
# RIGHT; reductions cannot have spaces in them, so put one in: 
 my @a = [[ <foo>],]; 
 # No ambiguity here, natural spaces between items suffice to resolve it: 
 my @a = [[<foo bar ber>],]; 

Less than vs. Word quoting/Associative indexing

# WRONG; trying to index 3 associatively: 
 say 3<5>4 
# RIGHT; prefer some extra whitespace around infix operators: 
 say 3 < 5 > 4 

Exclusive sequences vs. sequences with Ranges

See the section on operator traps for more information about how the ...^ operator can be mistaken for the ... operator with a ^ operator immediately following it. You must use whitespace correctly to indicate which interpretation will be followed.


Containers versus values in a capture

Beginners might expect a variable in a Capture to supply its current value when that Capture is later used. For example:

my $a = 2; say join ",", ($a, ++$a);  # OUTPUT: «3,3␤» 

Here the Capture contained the container pointed to by $a and the value of the result of the expression ++$a. Since the Capture must be reified before &say can use it, the ++$a may happen before &say looks inside the container in $a (and before the List is created with the two terms) and so it may already be incremented.

Instead, use an expression that produces a value when you want a value.

my $a = 2; say join ",", (+$a, ++$a); # OUTPUT: «2,3␤» 

Or even simpler

my $a = 2; say  "$a, {++$a}"; # OUTPUT: «2, 3␤» 

The same happens in this case:

my @arr; 
 my ($a, $b) = (1,1); 
 for ^5 { 
     ($a,$b) = ($b, $a+$b); 
     @arr.push: ($a, $b); 
     say @arr 

Outputs «[(1 2)]␤[(2 3) (2 3)]␤[(3 5) (3 5) (3 5)]␤.... $a and $b are not reified until say is called, the value that they have in that precise moment is the one printed. To avoid that, decontainerize values or take them out of the variable in some way before using them.

my @arr; 
 my ($a, $b) = (1,1); 
 for ^5 { 
     ($a,$b) = ($b, $a+$b); 
     @arr.push: ($a.item, $b.item); 
     say @arr 

With item, the container will be evaluated in item context, its value extracted, and the desired outcome achieved.

Cool tricks

Perl 6 includes a Cool class, which provides some of the DWIM behaviors we got used to by coercing arguments when necessary. However, DWIM is never perfect. Especially with Lists, which are Cool, there are many methods that will not do what you probably think they do, including contains, starts-with or index. Please see some examples in the section below.

Strings are not Lists, so beware indexing

In Perl 6, strings are not lists of characters. One cannot iterate over them or index into them as you can with lists, despite the name of the .index routine.

Lists become strings, so beware .index()ing

List inherits from Cool, which provides access to .index. Because of the way .index coerces a List into a Str, this can sometimes appear to be returning the index of an element in the list, but that is not how the behavior is defined.

my @a = <a b c d>; 
 say @a.index(‘a’);    # 0 
 say @a.index('c');    # 4 -- not 2! 
 say @a.index('b c');  # 2 -- not undefined! 
 say @a.index(<a b>);  # 0 -- not undefined! 

These same caveats apply to .rindex.

Lists become strings, so beware .contains()

Similarly, .contains does not look for elements in the list.

my @menu = <hamburger fries milkshake>; 
 say @menu.contains('hamburger');            # True 
 say @menu.contains('hot dog');              # False 
 say @menu.contains('milk');                 # True! 
 say @menu.contains('er fr');                # True! 
 say @menu.contains(<es mi>);                # True! 

If you actually want to check for the presence of an element, use the (cont) operator for single elements, and the superset and strict superset), _infix_⊃> operators for multiple elements.

my @menu = <hamburger fries milkshake>; 
 say @menu (cont) 'fries';                   # True 
 say @menu (cont) 'milk';                    # False 
 say @menu (>) <hamburger fries>;            # True 
 say @menu (>) <milkshake fries>;            # True (! NB: order doesn't matter) 

If you are doing a lot of element testing, you may be better off using a Set.

Numeric literals are parsed before coercion

Experienced programmers will probably not be surprised by this, but Numeric literals will be parsed into their numeric value before being coerced into a string, which may create nonintuitive results.

say 0xff.contains(55);      # True 
 say 0xff.contains(0xf);     # False 
 say 12_345.contains("23");  # True 
 say 12_345.contains("2_");  # False 

Getting a random item from a List

A common task is to retrieve one or more random elements from a collection, but List.rand isn't the way to do that. Cool provides rand, but that first coerces the List into the number of items in the list, and returns a random real number between 0 and that value. To get random elements, see pick and roll.

my @colors = <red orange yellow green blue indigo violet>; 
 say @colors.rand;       # 2.21921955680514 
 say @colors.pick;       # orange 
 say @colors.roll;       # blue 
 say @colors.pick(2);    # yellow violet  (cannot repeat) 
 say @colors.roll(3);    # red green red  (can repeat) 

Lists numify to their number of elements in numeric context

You want to check whether a number is divisible by any of a set of numbers:

say 42 %% <11 33 88 55 111 20325>; # OUTPUT: «True␤»

What? There's no single number 42 should be divisible by. However, that list has 6 elements, and 42 is divisible by 6. That's why the output is true. In this case, you should turn the List into a Junction:

say 42 %% <11 33 88 55 111 20325>.any; 
 # OUTPUT: «any(False, False, False, False, False, False)␤» 

which will clearly reveal the falsehood of the divisiveness of all the numbers in the list, which will be numified separately.


Referencing the last element of an array

In some languages one could reference the last element of an array by asking for the "-1th" element of the array, e.g.:

my @array = qw{victor alice bob charlie eve}; 
 say @array[-1];    # OUTPUT: «eve␤» 

In Perl 6 it is not possible to use negative subscripts, however the same is achieved by actually using a function, namely *-1. Thus, accessing the last element of an array becomes:

my @array = qw{victor alice bob charlie eve}; 
 say @array[*-1];   # OUTPUT: «eve␤» 

Yet another way is to utilize the array's tail method:

my @array = qw{victor alice bob charlie eve}; 
 say @array.tail;      # OUTPUT: «eve␤» 
 say @array.tail(2);   # OUTPUT: «(charlie eve)␤» 

Typed array parameters

Quite often new users will happen to write something like:

sub foo(Array @a) { ... } 

...before they have gotten far enough in the documentation to realize that this is asking for an Array of Arrays. To say that @a should only accept Arrays, use instead:

sub foo(@a where Array) { ... } 

It is also common to expect this to work, when it does not:

sub bar(Int @a) { 42.say }; 
 bar([1, 2, 3]);             # expected Positional[Int] but got Array 

The problem here is that [1, 2, 3] is not an Array[Int], it is a plain old Array that just happens to have Ints in it. To get it to work, the argument must also be an Array[Int].

my Int @b = 1, 2, 3; 
 bar(@b);                    # OUTPUT: «42␤» 
 bar(Array[Int].new(1, 2, 3)); 

This may seem inconvenient, but on the upside it moves the type-check on what is assigned to @b to where the assignment happens, rather than requiring every element to be checked on every call.

Using «» quoting when you don't need it

This trap can be seen in different varieties. Here are some of them:

my $x = ‘hello’; 
 my $y = ‘foo bar’; 
 my %h = $x => 42, $y => 99; 
 say %h«$x»;   # ← WRONG; assumption that $x has no whitespace 
 say %h«$y»;   # ← WRONG; splits ‘foo bar’ by whitespace 
 say %h«"$y"»; # ← KINDA OK; it works but there is no good reason to do that 
 say %h{$y};   # ← RIGHT; this is what should be used 
 run «touch $x»;        # ← WRONG; assumption that only one file will be created 
 run «touch $y»;        # ← WRONG; will touch file ‘foo’ and ‘bar’ 
 run «touch "$y"»;      # ← WRONG; better, but has a different issue if $y starts with - 
 run «touch -- "$y"»;   # ← KINDA OK; it works but there is no good enough reason to do that 
 run ‘touch’, ‘--’, $y; # ← RIGHT; explicit and *always* correct 
 run <touch -->, $y;    # ← RIGHT; < > are OK, this is short and correct 

Basically, «» quoting is only safe to use if you remember to always quote your variables. The problem is that it inverts the default behavior to unsafe variant, so just by forgetting some quotes you are risking to introduce either a bug or maybe even a security hole. To stay on the safe side, refrain from using «».


Some problems that might arise when dealing with strings.

Quotes and interpolation

Interpolation in string literals can be too clever for your own good.

# "HTML tags" interpreted as associative indexing: 
 "$foo<html></html>" eq 
# Parentheses interpreted as call with argument: 
 "$foo(" ~ @args ~ ")" eq 
 "$foo(' ~ @args ~ ')" 

You can avoid those problems using non-interpolating single quotes and switching to more liberal interpolation with \qq[] escape sequence:

my $a = 1; 
 say '\qq[$a]()$b()'; 
 # OUTPUT: «1()$b()␤» 

Another alternative is to use Q:c quoter, and use code blocks {} for all interpolation:

my $a = 1; 
 say Q:c«{$a}()$b()»; 
 # OUTPUT: «1()$b()␤» 

Strings are not iterable

There are methods that Str inherits from Any that work on iterables like lists. Iterators on strings contain one element that is the whole string. To use list-based methods like sort, reverse, you need to convert the string into a list first.

say "cba".sort;              # OUTPUT: «(cba)␤» 
 say "cba".comb.sort.join;    # OUTPUT: «abc␤» 

.chars gets the number of graphemes, not Codepoints

In Perl 6, .chars returns the number of graphemes, or user visible characters. These graphemes could be made up of a letter plus an accent for example. If you need the number of codepoints, you should use .codes. If you need the number of bytes when encoded as UTF8, you should use .encode.bytes to encode the string as UTF8 and then get the number of bytes.

say 'ǰ̣'.codes;        # OUTPUT: «2»
say 'ǰ̣'.chars;        # OUTPUT: «1»
say 'ǰ̣'.encode.bytes; # OUTPUT: «4»

For more information on how strings work in Perl 6, see the Unicode page.

All text is normalized by default

Perl 6 normalizes all text into Unicode NFC form (Normalization Form Canonical). Filenames are the only text not normalized by default. If you are expecting your strings to maintain a byte for byte representation as the original, you need to use UTF8-C8 when reading or writing to any filehandles.

Allomorphs generally follow numeric semantics

Str "0" is True, while Numeric is False. So what's the Bool value of allomorph <0>?

In general, allomorphs follow Numeric semantics, so the ones that numerically evaluate to zero are False:

say so   <0>; # OUTPUT: «False␤»
say so <0e0>; # OUTPUT: «False␤»
say so <0.0>; # OUTPUT: «False␤»

To force comparison being done for the Stringy part of the allomorph, use prefix ~ operator or the Str method to coerce the allomorph to Str, or use the chars routine to test whether the allomorph has any length:

say so      ~<0>;     # OUTPUT: «True␤»
say so       <0>.Str; # OUTPUT: «True␤»
say so chars <0>;     # OUTPUT: «True␤»

Case-insensitive comparison of strings

In order to do case-insensitive comparison, you can use .fc (fold-case). The problem is that people tend to use .lc or .uc, and it does seem to work within the ASCII range, but fails on other characters. This is not just a Perl 6 trap, the same applies to other languages.

say ‘groß’.lc eq ‘GROSS’.lc; # ← WRONG; False 
 say ‘groß’.uc eq ‘GROSS’.uc; # ← WRONG; True, but that's just luck 
 say ‘groß’.fc eq ‘GROSS’.fc; # ← RIGHT; True 

If you are working with regexes, then there is no need to use .fc and you can use :i (:ignorecase) adverb instead.


Constants on the left-hand side of pair notation

Consider this code:

enum Animals <Dog Cat>; 
 my %h := :{ Dog => 42 }; 
 say %h{Dog}; # OUTPUT: «(Any)␤» 

The :{ … } syntax is used to create object hashes. The intentions of someone who wrote that code were to create a hash with Enum objects as keys (and say %h{Dog} attempts to get a value using the Enum object to perform the lookup). However, that's not how pair notation works.

For example, in Dog => 42 the key will be a Str. That is, it doesn't matter if there is a constant, or an enumeration with the same name. The pair notation will always use the left-hand side as a string literal, as long as it looks like an identifier.

To avoid this, use (Dog) => 42 or ::Dog => 42.

Scalar values within Pair

When dealing with Scalar values, the Pair holds the container to the value. This means that it is possible to reflect changes to the Scalar value from outside the Pair:

my $v = 'value A'; 
 my $pair = Pair.new( 'a', $v ); 
 $pair.say;  # OUTPUT: a => value A 
 $v = 'value B'; 
 $pair.say; # OUTPUT: a => value B 

Use the method freeze to force the removal of the Scalar container from the Pair. For more details see the documentation about Pair.

Sets, bags and mixes

Sets, bags and mixes do not have a fixed order

When iterating over this kind of objects, an order is not defined.

my $set = <a b c>.Set; 
 .say for $set.list; # OUTPUT: «a => True␤c => True␤b => True␤» 
 # OUTPUT: «a => True␤c => True␤b => True␤» 
 # OUTPUT: «c => True␤b => True␤a => True␤» 

Every iteration might (and will) yield a different order, so you cannot trust a particular sequence of the elements of a set. If order does not matter, just use them that way. If it does, use sort

my $set = <a b c>.Set;
.say for $set.list.sort;  # OUTPUT: «a => True␤b => True␤c => True␤»

In general, sets, bags and mixes are unordered, so you should not depend on them having a particular order.


Some operators commonly shared among other languages were repurposed in Perl 6 for other, more common, things:


The ^, |, and & are not bitwise operators, they create Junctions. The corresponding bitwise operators in Perl 6 are: +^, +|, +& for integers and ?^, ?|, ?& for booleans.

Exclusive sequence operator

Lavish use of whitespace helps readability, but keep in mind infix operators cannot have any whitespace in them. One such operator is the sequence operator that excludes right point: ...^ (or its Unicode equivalent …^).

say 1... ^5; # OUTPUT: «(1 0 1 2 3 4)␤»
say 1...^5;  # OUTPUT: «(1 2 3 4)␤»

If you place whitespace between the ellipsis () and the caret (^), it's no longer a single infix operator, but an infix inclusive sequence operator () and a prefix Range operator (^). Iterables are valid endpoints for the sequence operator, so the result you'll get might not be what you expected.

String ranges/Sequences

In some languages, using strings as range end points, considers the entire string when figuring out what the next string should be; loosely treating the strings as numbers in a large base. Here's Perl 5 version:

say join ", ", "az".."bc"; 
 # OUTPUT: «az, ba, bb, bc␤» 

Such a range in Perl 6 will produce a different result, where each letter will be ranged to a corresponding letter in the end point, producing more complex sequences:

say join ", ", "az".."bc"; 
 #`{ OUTPUT: « 
     az, ay, ax, aw, av, au, at, as, ar, aq, ap, ao, an, am, al, ak, aj, ai, ah, 
     ag, af, ae, ad, ac, bz, by, bx, bw, bv, bu, bt, bs, br, bq, bp, bo, bn, bm, 
     bl, bk, bj, bi, bh, bg, bf, be, bd, bc 
say join ", ", "r2".."t3"; 
 # OUTPUT: «r2, r3, s2, s3, t2, t3␤» 

To achieve simpler behavior, similar to the Perl 5 example above, use a sequence operator that calls .succ method on the starting string:

say join ", ", ("az", *.succ ... "bc"); 
 # OUTPUT: «az, ba, bb, bc␤» 

Topicalizing operators

The smartmatch operator ~~ and andthen set the topic $_ to their left-hand-side. In conjunction with implicit method calls on the topic this can lead to surprising results.

my &method = { note $_; $_ }; 
 $_ = 'object'; 
 say .&method; 
 # OUTPUT: «object␤object␤» 
 say 'topic' ~~ .&method; 
 # OUTPUT: «topic␤True␤» 

In many cases flipping the method call to the LHS will work.

my &method = { note $_; $_ }; 
 $_ = 'object'; 
 say .&method; 
 # OUTPUT: «object␤object␤» 
 say .&method ~~ 'topic'; 
 # OUTPUT: «object␤False␤» 

Fat arrow and constants

The fat arrow operator => will turn words on its left-hand side to Str without checking the scope for constants or \-sigiled variables. Use explicit scoping to get what you mean.

constant V = 'x'; 
 my %h = V => 'oi‽', ::V => 42; 
 say %h.perl 
 # OUTPUT: «{:V("oi‽"), :x(42)}␤» 

Infix operator assignment

Infix operators, both built in and user defined, can be combined with the assignment operator as this addition example demonstrates:

my $x = 10;
$x += 20;
say $x;     # OUTPUT: «30␤»

For any given infix operator op, L op= R is equivalent to L = L op R (where L and R are the left and right arguments, respectively). This means that the following code may not behave as expected:

my @a = 1, 2, 3;
@a += 10;
say @a;  # OUTPUT: «[13]␤»

Coming from a language like C++, this might seem odd. It is important to bear in mind that += isn't defined as method on the left hand argument (here the @a array) but is simply shorthand for:

my @a = 1, 2, 3;
@a = @a + 10;
say @a;  # OUTPUT: «[13]␤»

Here @a is assigned the result of adding @a (which has three elements) and 10; 13 is therefore placed in @a.

Use the hyper form of the assignment operators instead:

my @a = 1, 2, 3;
@a »+=» 10;
say @a;  # OUTPUT: «[11 12 13]␤»


$x vs <$x>, and $(code) vs <{code}>

Perl 6 offers several constructs to generate regexes at runtime through interpolation (see their detailed description here). When a regex generated this way contains only literals, the above constructs behave (pairwise) identically, as if they are equivalent alternatives. As soon as the generated regex contains metacharacters, however, they behave differently, which may come as a confusing surprise.

The first two constructs that may easily be confused with each other are $variable and <$variable>:

my $variable = 'camelia';
say ‘I ♥ camelia’ ~~ /  $variable  /;   # OUTPUT: 「camelia」
say ‘I ♥ camelia’ ~~ / <$variable> /;   # OUTPUT: 「camelia」

Here they act the same because the value of $variable consists of literals. But when the variable is changed to comprise regex metacharacters the outputs become different:

my $variable = '#camelia';
say ‘I ♥ #camelia’ ~~ /  $variable  /;   # OUTPUT: 「#camelia」
say ‘I ♥ #camelia’ ~~ / <$variable> /;   # !! Error: malformed regex

What happens here is that the string #camelia contains the metacharacter #. In the context of a regex, this character should be quoted to match literally; without quoting, the # is parsed as the start of a comment that runs until the end of the line, which in turn causes the regex not to be terminated, and thus to be malformed.

Two other constructs that must similarly be distinguished from one another are $(code) and <{code}>. Like before, as long as the (stringified) return value of code comprises only literals, there is no distinction between the two:

my $variable = 'ailemac';
say ‘I ♥ camelia’ ~~ / $($variable.flip)   /;   # OUTPUT: 「camelia」
say ‘I ♥ camelia’ ~~ / <{$variable.flip}>  /;   # OUTPUT: 「camelia」

But when the return value is changed to comprise regex metacharacters, the outputs diverge:

my $variable = 'ailema.';
say ‘I ♥ camelia’ ~~ / $($variable.flip)   /;   # OUTPUT: Nil
say ‘I ♥ camelia’ ~~ / <{$variable.flip}>  /;   # OUTPUT: 「camelia」

In this case the return value of the code is the string .amelia, which contains the metacharacter .. The above attempt by $(code) to match the dot literally fails; the attempt by <{code}> to match the dot as a regex wildcard succeeds. Hence the different outputs.

| vs ||: which branch will win

To match one of several possible alternatives, || or | will be used. But they are so different.

When there are multiple matching alternations, for those separated by ||, the first matching alternation wins; for those separated by |, which to win is decided by LTM strategy. See also: documentation on || and documentation on |.

For simple regexes just using || instead of | will get you familiar semantics, but if writing grammars then it's useful to learn about LTM and declarative prefixes and prefer |. And keep yourself away from using them in one regex. When you have to do that, add parentheses and ensure that you know how LTM strategy works to make the code do what you want.

The trap typically arises when you try to mix both | and || in the same regex:

say 42 ~~ / [  0 || 42 ] | 4/; # OUTPUT: «「4」␤» 
 say 42 ~~ / [ 42 ||  0 ] | 4/; # OUTPUT: «「42」␤» 

The code above may seem like it is producing a wrong result, but the implementation is actually right.

$/ changes each time a regular expression is matched

Each time a regular expression is matched against something, the special variable $/ holding the result Match object is changed accordingly to the result of the match (that could also be Nil).

The $/ is changed without any regard to the scope the regular expression is matched within.

For further information and examples please see the related section in the Regular Expressions documentation.

<foo> vs. < foo>: named rules vs. quoted lists

Regexes can contain quoted lists; longest token matching is performed on the list's elements as if a | alternation had been specified (see here for further information).

Within a regex, the following are lists with a single item, 'foo':

say 'foo' ~~ /< foo >/;  # OUTPUT: «「foo」␤»
say 'foo' ~~ /< foo>/;   # OUTPUT: «「foo」␤»

but this is a call to the named rule foo:

say 'foo' ~~ /<foo>/; 
 # OUTPUT: «No such method 'foo' for invocant of type 'Match'␤ in block <unit> at <unknown file> line 1␤» 

Be wary of the difference; if you intend to use a quoted list, ensure that whitespace follows the initial <.

Non-capturing, non-global matching in list context

Unlike Perl 5, non-capturing and non-global matching in list context doesn't produce any values:

if  'x' ~~ /./ { say 'yes' }  # OUTPUT: «yes␤»
for 'x' ~~ /./ { say 'yes' }  # NO OUTPUT

This is because its 'list' slot (inherited from Capture class) doesn't get populated with the original Match object:

say ('x' ~~ /./).list  # OUTPUT: «()␤»

To achieve the desired result, use global matching, capturing parentheses or a list with a trailing comma:

for 'x' ~~ m:g/./ { say 'yes' }  # OUTPUT: «yes␤»
for 'x' ~~ /(.)/  { say 'yes' }  # OUTPUT: «yes␤»
for ('x' ~~ /./,) { say 'yes' }  # OUTPUT: «yes␤»

Common precedence mistakes

Adverbs and precedence

Adverbs do have a precedence that may not follow the order of operators that is displayed on your screen. If two operators of equal precedence are followed by an adverb it will pick the first operator it finds in the abstract syntax tree. Use parentheses to help Perl 6 understand what you mean or use operators with looser precedence.

my %x = a => 42; 
 say !%x<b>:exists;            # dies with X::AdHoc 
 say %x<b>:!exists;            # this works 
 say !(%x<b>:exists);          # works too 
 say not %x<b>:exists;         # works as well 
 say True unless %x<b>:exists; # avoid negation altogether 

Ranges and precedence

The loose precedence of .. can lead to some errors. It is usually best to parenthesize ranges when you want to operate on the entire range.

1..3.say;    # says "3" (and warns about useless "..") 
 (1..3).say;  # says "1..3" 

Loose boolean operators

The precedence of and, or, etc. is looser than routine calls. This can have surprising results for calls to routines that would be operators or statements in other languages like return, last and many others.

sub f { 
     return True and False; 
     # this is actually 
     # (return True) and False; 
 say f; # OUTPUT: «True␤» 

Exponentiation operator and prefix minus

say -1²;   # OUTPUT: «-1␤» 
 say -1**2; # OUTPUT: «-1␤» 

When performing a regular mathematical calculation, the power takes precedence over the minus; so -1² can be written as -(1²). Perl 6 matches these rules of mathematics and the precedence of ** operator is tighter than that of the prefix -. If you wish to raise a negative number to a power, use parentheses:

say (-1)²;   # OUTPUT: «1␤» 
 say (-1)**2; # OUTPUT: «1␤» 

Method operator calls and prefix minus

Prefix minus binds looser than dotty method op calls. The prefix minus will be applied to the return value from the method. To ensure the minus gets passed as part of the argument, enclose in parenthesis.

say  -1.abs;  # OUTPUT: «-1␤» 
 say (-1).abs; # OUTPUT: «1␤» 

Subroutine and method calls

Subroutine and method calls can be made using one of two forms:

foo(...); # function call form, where ... represent the required arguments 
 foo ...;  # list op form, where ... represent the required arguments 

The function call form can cause problems for the unwary when whitespace is added after the function or method name and before the opening parenthesis.

First we consider functions with zero or one parameter:

sub foo() { say 'no arg' } 
 sub bar($a) { say "one arg: $a" } 

Then execute each with and without a space after the name:

foo();    # okay: no arg 
 foo ();   # FAIL: Too many positionals passed; expected 0 arguments but got 1 
 bar($a);  # okay: one arg: 1 
 bar ($a); # okay: one arg: 1 

Now declare a function of two parameters:

sub foo($a, $b) { say "two args: $a, $b" } 

Execute it with and without the space after the name:

foo($a, $b);  # okay: two args: 1, 2 
 foo ($a, $b); # FAIL: Too few positionals passed; expected 2 arguments but got 1 

The lesson is: "be careful with spaces following sub and method names when using the function call format." As a general rule, good practice might be to avoid the space after a function name when using the function call format.

Note that there are clever ways to eliminate the error with the function call format and the space, but that is bordering on hackery and will not be mentioned here. For more information, consult Functions.

Finally, note that, currently, when declaring the functions whitespace may be used between a function or method name and the parentheses surrounding the parameter list without problems.

Named parameters

Many built-in subroutines and method calls accept named parameters and your own code may accept them as well, but be sure the arguments you pass when calling your routines are actually named parameters:

sub foo($a, :$b) { ... } 
 foo(1, 'b' => 2); # FAIL: Too many positionals passed; expected 1 argument but got 2 

What happened? That second argument is not a named parameter argument, but a Pair passed as a positional argument. If you want a named parameter it has to look like a name to Perl:

foo(1, b => 2); # okay 
 foo(1, :b(2));  # okay 
 foo(1, :b<it>); # okay 
 my $b = 2; 
 foo(1, :b($b)); # okay, but redundant 
 foo(1, :$b);    # okay 
 # Or even... 
 my %arg = 'b' => 2; 
 foo(1, |%arg);  # okay too 

That last one may be confusing, but since it uses the | prefix on a Hash, which is a special compiler construct indicating you want to use the contents of the variable as arguments, which for hashes means to treat them as named arguments.

If you really do want to pass them as pairs you should use a List or Capture instead:

my $list = ('b' => 2),; # this is a List containing a single Pair 
 foo(|$list, :$b);       # okay: we passed the pair 'b' => 2 to the first argument 
 foo(1, |$list);         # FAIL: Too many positionals passed; expected 1 argument but got 2 
 foo(1, |$list.Capture); # OK: .Capture call converts all Pair objects to named args in a Capture 
my $cap = \('b' => 2); # a Capture with a single positional value 
 foo(|$cap, :$b); # okay: we passed the pair 'b' => 2 to the first argument 
 foo(1, |$cap);   # FAIL: Too many positionals passed; expected 1 argument but got 2 

A Capture is usually the best option for this as it works exactly like the usual capturing of routine arguments during a regular call.

The nice thing about the distinction here is that it gives the developer the option of passing pairs as either named or positional arguments, which can be handy in various instances.

Argument count limit

While it is typically unnoticeable, there is a backend-dependent argument count limit. Any code that does flattening of arbitrarily sized arrays into arguments won't work if there are too many elements.

my @a = 1 xx 9999; 
 my @b; 
 @b.push: |@a; 
 say @b.elems # OUTPUT: «9999␤» 
my @a = 1 xx 999999; 
 my @b; 
 @b.push: |@a; # OUTPUT: «Too many arguments in flattening array.␤  in block <unit> at <tmp> line 1␤␤» 

Avoid this trap by rewriting the code so that there is no flattening. In the example above, you can replace push with append. This way, no flattening is required because the array can be passed as is.

my @a = 1 xx 999999; 
 my @b; 
 @b.append: @a; 
 say @b.elems # OUTPUT: «999999␤» 

Phasers and implicit return

sub returns-ret () { 
     CATCH { 
         default {} 
 sub doesn't-return-ret () { 
     CATCH { 
         default {} 
 say returns-ret;        # OUTPUT: «ret» 
 say doesn't-return-ret; 
 # BAD: outputs «Nil» and a warning «Useless use of constant string "ret" in sink context (line 13)» 

Code for returns-ret and doesn't-return-ret might look exactly the same, since in principle it does not matter where the CATCH block goes. However, a block is an object and the last object in a sub will be returned, so the doesn't-return-ret will return Nil, and, besides, since "ret" will be now in sink context, it will issue a warning. In case you want to place phasers last for conventional reasons, use the explicit form of return.

sub explicitly-return-ret () { 
     return "ret"; 
     CATCH { 
         default {} 

Input and output

Closing open filehandles and pipes

Unlike some other languages, Perl 6 does not use reference counting, and so the filehandles are NOT closed when they go out of scope. You have to explicitly close them either by using close routine or using the :close argument several of IO::Handle's methods accept. See IO::Handle.close for details.

The same rules apply to IO::Handle's subclass IO::Pipe, which is what you operate on when reading from a Proc you get with routines run and shell.

The caveat applies to IO::CatHandle type as well, though not as severely. See IO::CatHandle.close for details.

IO::Path stringification

Partly for historical reasons and partly by design, an IO::Path object stringifies without considering its CWD attribute, which means if you chdir and then stringify an IO::Path, or stringify an IO::Path with custom $!CWD attribute, the resultant string won't reference the original filesystem object:

with 'foo'.IO { 
     .Str.say;       # OUTPUT: «foo␤» 
     .relative.say;  # OUTPUT: «foo␤» 
     chdir "/tmp"; 
     .Str.say;       # OUTPUT: «foo␤» 
     .relative.say   # OUTPUT: «../home/camelia/foo␤» 
 # Deletes ./foo, not /bar/foo 
 unlink IO::Path.new("foo", :CWD</bar>).Str 

The easy way to avoid this issue is to not stringify an IO::Path object at all. Core routines that work with paths can take an IO::Path object, so you don't need to stringify the paths.

If you do have a case where you need a stringified version of an IO::Path, use absolute or relative methods to stringify it into an absolute or relative path, respectively.

If you are facing this issue because you use chdir in your code, consider rewriting it in a way that does not involve changing the current directory. For example, you can pass cwd named argument to run without having to use chdir around it.

Splitting the input data into lines

There is a difference between using .lines on IO::Handle and on a Str. The trap arises if you start assuming that both split data the same way.

say $_.perl for $*IN.lines # .lines called on IO::Handle 
 # "foox" 
 # "fooy\rbar" 
 # "fooz" 

As you can see in the example above, there was a line which contained \r (“carriage return” control character). However, the input is split strictly by \n, so \r was kept as part of the string.

On the other hand, Str.lines attempts to be “smart” about processing data from different operating systems. Therefore, it will split by all possible variations of a newline.

say $_.perl for $*IN.slurp(:bin).decode.lines # .lines called on a Str 
 # "foox" 
 # "fooy" 
 # "bar" 
 # "fooz" 

The rule is quite simple: use IO::Handle.lines when working with programmatically generated output, and Str.lines when working with user-written texts.

Use $data.split(“\n”) in cases where you need the behavior of IO::Handle.lines but the original IO::Handle is not available.


Note that if you really want to slurp the data first, then you will have to use .IO.slurp(:bin).decode.split(“\n”). Notice how we use :bin to prevent it from doing the decoding, only to call .decode later anyway. All that is needed because .slurp is assuming that you are working with text and therefore it attempts to be smart about newlines.


If you are using Proc::Async, then there is currently no easy way to make it split data the right way. You can try reading the whole output and then using Str.split (not viable if you are dealing with large data) or writing your own logic to split the incoming data the way you need. Same applies if your data is null-separated.

Proc::Async and print

When using Proc::Async you should not assume that .print (or any other similar method) is synchronous. The biggest issue of this trap is that you will likely not notice the problem by running the code once, so it may cause a hard-to-detect intermittent fail.

Here is an example that demonstrates the issue:

loop { 
     my $proc = Proc::Async.new: :w, ‘head’, ‘-n’, ‘1’; 
     my $got-something; 
     react { 
         whenever $proc.stdout.lines { $got-something = True } 
         whenever $proc.start        { die ‘FAIL!’ unless $got-something } 
         $proc.print: “one\ntwo\nthree\nfour”; 
     say $++; 

And the output it may produce:

 An operation first awaited: 
   in block <unit> at print.p6 line 4 
 Died with the exception: 
       in block  at print.p6 line 6 

Resolving this is easy because .print returns a promise that you can await on. The solution is even more beautiful if you are working in a react block:

whenever $proc.print: “one\ntwo\nthree\nfour” { 

Using .stdout without .lines

Method .stdout of Proc::Async returns a supply that emits chunks of data, not lines. The trap is that sometimes people assume it to give lines right away.

my $proc = Proc::Async.new(‘cat’, ‘/usr/share/dict/words’); 
 react { 
     whenever $proc.stdout.head(1) { .say } # ← WRONG (most likely) 
     whenever $proc.start { } 

The output is clearly not just 1 line:


If you want to work with lines, then use $proc.stdout.lines. If you're after the whole output, then something like this should do the trick: whenever $proc.stdout { $out ~= $_ }.

Exception handling

Sunk Proc

Some methods return a Proc object. If it represents a failed process, Proc itself won't be exception-like, but sinking it will cause an X::Proc::Unsuccessful exception to be thrown. That means this construct will throw, despite the try in place:

try run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «The spawned process exited unsuccessfully (exit code: 42)␤» 

This is because try receives a Proc and returns it, at which point it sinks and throws. Explicitly sinking it inside the try avoids the issue and ensures the exception is thrown inside the try:

try sink run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «still alive␤» 

If you're not interested in catching any exceptions, then use an anonymous variable to keep the returned Proc in; this way it'll never sink:

$ = run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «still alive␤» 

Using shortcuts

The ^ twigil

Using the ^ twigil can save a fair amount of time and space when writing out small blocks of code. As an example:

for 1..8 -> $a, $b { say $a + $b; } 

can be shortened to just

for 1..8 { say $^a + $^b; } 

The trouble arises when a person wants to use more complex names for the variables, instead of just one letter. The ^ twigil is able to have the positional variables be out of order and named whatever you want, but assigns values based on the variable's Unicode ordering. In the above example, we can have $^a and $^b switch places, and those variables will keep their positional values. This is because the Unicode character 'a' comes before the character 'b'. For example:

# In order 
 sub f1 { say "$^first $^second"; } 
 f1 "Hello", "there";    # OUTPUT: «Hello there␤» 
# Out of order 
 sub f2 { say "$^second $^first"; } 
 f2 "Hello", "there";    # OUTPUT: «there Hello␤» 

Due to the variables allowed to be called anything, this can cause some problems if you are not accustomed to how Perl 6 handles these variables.

# BAD NAMING: alphabetically `four` comes first and gets value `1` in it: 
 for 1..4 { say "$^one $^two $^three $^four"; }    # OUTPUT: «2 4 3 1␤» 
 # GOOD NAMING: variables' naming makes it clear how they sort alphabetically: 
 for 1..4 { say "$^a $^b $^c $^d"; }               # OUTPUT: «1 2 3 4␤» 

Using » and map interchangeably

While » may look like a shorter way to write map, they differ in some key aspects.

First, the » includes a hint to the compiler that it may autothread the execution, thus if you're using it to call a routine that produces side effects, those side effects may be produced out of order (the result of the operator is kept in order, however). Also if the routine being invoked accesses a resource, there's the possibility of a race condition, as multiple invocations may happen simultaneously, from different threads.

This is an actual output from Rakudo 2015.09
<a b c d>».say # OUTPUT: «d␤b␤c␤a␤» 

Second, » checks the nodality of the routine being invoked and based on that will use either deepmap or nodemap to map over the list, which can be different from how a map call would map over it:

say ((1, 2, 3), [^4], '5')».Numeric;       # OUTPUT: «((1 2 3) [0 1 2 3] 5)␤» 
 say ((1, 2, 3), [^4], '5').map: *.Numeric; # OUTPUT: «(3 4 5)␤» 

The bottom line is that map and » are not interchangeable, but using one instead of the other is OK as long as you understand the differences.

Word splitting in « »

Keep in mind that « » performs word splitting similarly to how shells do it, so many shell pitfalls apply here as well (especially when using in combination with run):

my $file = ‘--my arbitrary filename’;
run ‘touch’, ‘--’, $file;  # RIGHT
run <touch -->, $file;     # RIGHT

run «touch -- "$file"»;    # RIGHT but WRONG if you forget quotes
run «touch -- $file»;      # WRONG; touches ‘--my’, ‘arbitrary’ and ‘filename’
run ‘touch’, $file;        # WRONG; error from `touch`
run «touch "$file"»;       # WRONG; error from `touch`

Note that -- is required for many programs to disambiguate between command-line arguments and filenames that begin with hyphens.


Using a once block

The once block is a block of code that will only run once when its parent block is run. As an example:

my $var = 0; 
 for 1..10 { 
     once { $var++; } 
 say "Variable = $var";    # OUTPUT: «Variable = 1␤» 

This functionality also applies to other code blocks like sub and while, not just for loops. Problems arise though, when trying to nest once blocks inside of other code blocks:

my $var = 0; 
 for 1..10 { 
     do { once { $var++; } } 
 say "Variable = $var";    # OUTPUT: «Variable = 10␤» 

In the above example, the once block was nested inside of a code block which was inside of a for loop code block. This causes the once block to run multiple times, because the once block uses state variables to determine whether it has run previously. This means that if the parent code block goes out of scope, then the state variable the once block uses to keep track of if it has run previously, goes out of scope as well. This is why once blocks and state variables can cause some unwanted behavior when buried within more than one code block.

If you want to have something that will emulate the functionality of a once block, but still work when buried a few code blocks deep, we can manually build the functionality of a once block. Using the above example, we can change it so that it will only run once, even when inside the do block by changing the scope of the state variable.

my $var = 0; 
 for 1..10 { 
     state $run-code = True; 
     do { if ($run-code) { $run-code = False; $var++; } } 
 say "Variable = $var";    # OUTPUT: «Variable = 1␤» 

In this example, we essentially manually build a once block by making a state variable called $run-code at the highest level that will be run more than once, then checking to see if $run-code is True using a regular if. If the variable $run-code is True, then make the variable False and continue with the code that should only be completed once.

The main difference between using a state variable like the above example and using a regular once block is what scope the state variable is in. The scope for the state variable created by the once block, is the same as where you put the block (imagine that the word 'once' is replaced with a state variable and an if to look at the variable). The example above using state variables works because the variable is at the highest scope that will be repeated; whereas the example that has a once block inside of a do, made the variable within the do block which is not the highest scope that is repeated.

Using a once block inside a class method will cause the once state to carry across all instances of that class. For example:

class A { 
     method sayit() { once say 'hi' } 
 my $a = A.new; 
 $a.sayit;      # OUTPUT: «hi␤» 
 my $b = A.new; 
 $b.sayit;      # nothing 

LEAVE phaser and exit

Using LEAVE phaser to perform graceful resource termination is a common pattern, but it does not cover the case when the program is stopped with exit.

The following nondeterministic example should demonstrate the complications of this trap:

my $x = say ‘Opened some resource’; 
 LEAVE say ‘Closing the resource gracefully’ with $x; 
 exit 42 if rand < ⅓; # ① 「exit」 is bad 
 die ‘Dying because of unhandled exception’ if rand < ½; # ② 「die」 is ok 
 # fallthru ③ 

There are three possible results:

 Opened some resource 
 Opened some resource 
 Closing the resource gracefully 
 Dying because of unhandled exception 
   in block <unit> at print.p6 line 5 
 Opened some resource 
 Closing the resource gracefully 

A call to exit is part of normal operation for many programs, so beware unintentional combination of LEAVE phasers and exit calls.

LEAVE phaser may run sooner than you think

Parameter binding is executed when we're "inside" the routine's block, which means LEAVE phaser would run when we leave that block if parameter binding fails when wrong arguments are given:

sub foo(Int) { 
     my $x = 42; 
     LEAVE say $x.Int; # ← WRONG; assumes that $x is set 
 say foo rand; # OUTPUT: «No such method 'Int' for invocant of type 'Any'␤» 

A simple way to avoid this issue is to declare your sub or method a multi, so the candidate is eliminated during dispatch and the code never gets to binding anything inside the sub, thus never entering the routine's body:

multi foo(Int) { 
     my $x = 42; 
     LEAVE say $x.Int; 
 say foo rand; # OUTPUT: «Cannot resolve caller foo(Num); none of these signatures match: (Int)␤» 

Another alternative is placing the LEAVE into another block (assuming it's appropriate for it to be executed when that block is left, not the routine's body:

sub foo(Int) { 
     my $x = 42; 
     { LEAVE say $x.Int; } 
 say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.7289418947969465e0)␤» 

You can also ensure LEAVE can be executed even if the routine is left due to failed argument binding. In our example, we check $x is defined before doing anything with it.

sub foo(Int) { 
     my $x = 42; 
     LEAVE $x andthen .Int.say; 
 say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.8517160389079508e0)␤» 


Using regexes within grammar's actions

grammar will-fail { 
     token TOP {^ <word> $} 
     token word { \w+ } 
 class will-fail-actions { 
     method TOP ($/) { my $foo = ~$/; say $foo ~~ /foo/;  } 

Will fail with Cannot assign to a readonly variable ($/) or a value on method TOP. The problem here is that regular expressions also affect $/. Since it is in TOP's signature, it is a read-only variable, which is what produces the error. You can safely either use another variable in the signature or add is copy, this way:

method TOP ($/ is copy) { my $foo = ~$/; my $v = $foo ~~ /foo/;  } 

Using certain names for rules/token/regexes

Grammars are actually a type of classes.

grammar G {};
say G.^mro; # OUTPUT: «((G) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))␤»

^mro prints the class hierarchy of this empty grammar, showing all the superclasses. And these superclasses have their very own methods. Defining a method in that grammar might clash with the ones inhabiting the class hierarchy:

grammar g { 
     token TOP { <item> }; 
     token item { 'defined' } 
 say g.parse('defined'); 
 # OUTPUT: «Too many positionals passed; expected 1 argument but got 2␤  in regex item at /tmp/grammar-clash.p6 line 3␤  in regex TOP at /tmp/grammar-clash.p6 line 2␤  in block <unit> at /tmp/grammar-clash.p6 line 5» 

item seems innocuous enough, but it is a sub defined in class Mu. The message is a bit cryptic and totally unrelated to that fact, but that is why this is listed as a trap. In general, all subs defined in any part of the hierarchy are going to cause problems; some methods will too. For instance, CREATE, take and defined (which are defined in Mu). In general, multi methods and simple methods will not have any problem, but it might not be a good practice to use them as rule names.

Also avoid phasers for rule/token/regex names: TWEAK, BUILD, BUILD-ALL will throw another kind of exception if you do that: Cannot find method 'match': no method cache and no .^find_method, once again only slightly related to what is actually going on.

Unfortunate generalization

:exists with more than one key

Let's say you have a hash and you want to use :exists on more than one element:

my %h = a => 1, b => 2; 
 say ‘a exists’ if %h<a>:exists;   # ← OK; True 
 say ‘y exists’ if %h<y>:exists;   # ← OK; False 
 say ‘Huh‽’     if %h<x y>:exists; # ← WRONG; returns a 2-item list 

Did you mean “if any of them exists”, or did you mean that all of them should exist? Use any or all Junction to clarify:

my %h = a => 1, b => 2; 
 say ‘x or y’     if any %h<x y>:exists;   # ← RIGHT (any); False 
 say ‘a, x or y’  if any %h<a x y>:exists; # ← RIGHT (any); True 
 say ‘a, x and y’ if all %h<a x y>:exists; # ← RIGHT (all); False 
 say ‘a and b’    if all %h<a b>:exists;   # ← RIGHT (all); True 

The reason why it is always True (without using a junction) is that it returns a list with Bool values for each requested lookup. Non-empty lists always give True when you Boolify them, so the check always succeeds no matter what keys you give it.

Using […] metaoperator with a list of lists

Every now and then, someone gets the idea that they can use [Z] to create the transpose of a list-of-lists:

my @matrix = <X Y>, <a b>, <1 2>; 
 my @transpose = [Z] @matrix; # ← WRONG; but so far so good ↙ 
 say @transpose;              # [(X a 1) (Y b 2)] 

And everything works fine, until you get an input @matrix with exactly one row (child list):

my @matrix = <X Y>,; 
 my @transpose = [Z] @matrix; # ← WRONG; ↙ 
 say @transpose;              # [(X Y)] – not the expected transpose [(X) (Y)] 

This happens partly because of the single argument rule, and there are other cases when this kind of a generalization may not work.

Using [~] for concatenating a list of blobs

The ~ infix operator can be used to concatenate Strs or Blobs. However, an empty list will always be reduced to an empty Str. This is due to the fact that, in the presence of a list with no elements, the reduction metaoperator returns the identity element for the given operator. Identity element for ~ is an empty string, regardless of the kind of elements the list could be populated with.

my Blob @chunks; 
 say ([~] @chunks).perl; # OUTPUT: «""␤» 

This might cause a problem if you attempt to use the result while assuming that it is a Blob:

my Blob @chunks; 
 say ([~] @chunks).decode; 
 # OUTPUT: «No such method 'decode' for invocant of type 'Str'. Did you mean 'encode'?␤…» 

There are many ways to cover that case. You can avoid [ ] metaoperator altogether:

my @chunks; 
 # … 
 say Blob.new: |«@chunks; # OUTPUT: «Blob:0x<>␤» 

Alternatively, you can initialize the array with an empty Blob:

my @chunks = Blob.new; 
 # … 
 say [~] @chunks; # OUTPUT: «Blob:0x<>␤» 

Or you can utilize || operator to make it use an empty Blob in case the list is empty:

my @chunks; 
 # … 
 say [~] @chunks || Blob.new; # OUTPUT: «Blob:0x<>␤» 

Please note that a similar issue may arise when reducing lists with other operators.


Beware of nesting Maps in sink context

Maps apply an expression to every element of a List and return a Seq:

say <þor oðin loki>.map: *.codes; # OUTPUT: «(3 4 4)␤»

Maps are often used as a compact substitute for a loop, performing some kind of action in the map code block:

<þor oðin loki>.map: *.codes.say; # OUTPUT: «3␤4␤4␤»

The problem might arise when maps are nested and in a sink context.

<foo bar ber>.map: { $^a.comb.map: { $^b.say}}; # OUTPUT: «»

You might expect the innermost map to bubble the result up to the outermost map, but it simply does nothing. Maps return Seqs, and in sink context the innermost map will iterate and discard the produced values, which is why it yields nothing.

Simply using say at the beginning of the sentence will save the result from sink context:

say <foo bar ber>.map: *.comb.map: *.say ;
# OUTPUT: «f␤o␤o␤b␤a␤r␤b␤e␤r␤((True True True) (True True True) (True True True))␤»

However, it will not be working as intended; the first f␤o␤o␤b␤a␤r␤b␤e␤r␤ is the result of the innermost say, but then say returns a Bool, True in this case. Those Trues are what get printed by the outermost say, one for every letter. A much better option would be to flatten the outermost sequence:

<foo bar ber>.map({ $^a.comb.map: { $^b.say}}).flat
# OUTPUT: «f␤o␤o␤b␤a␤r␤b␤e␤r␤»

Of course, saving say for the result will also produce the intended result, as it will be saving the two nested sequences from void context:

say <foo bar ber>.map: { $^þ.comb }; # OUTPUT: « ((f o o) (b a r) (b e r))»


The smartmatch operator shortcuts to the right hand side accepting the left hand side. This may cause some confusion.

Smartmatch and WhateverCode

Using WhateverCode in the left hand side of a smartmatch does not work as expected, or at all:

my @a = <1 2 3>; 
 say @a.grep( *.Int ~~ 2 ); 
 # OUTPUT: «Cannot use Bool as Matcher with '.grep'.  Did you mean to 
 # use $_ inside a block?␤␤␤» 

The error message does not make a lot of sense. It does, however, if you put it in terms of the ACCEPTS method: that code is equivalent to 2.ACCEPTS( *.Int ), but *.Int cannot be coerced to Numeric, being as it is a Block.

Solution: don't use WhateverCode in the left hand side of a smartmatch:

my @a = <1 2 3>; 
 say @a.grep( 2 ~~ *.Int ); # OUTPUT: «(2)␤» 

41 Fundamental topics


42 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 different 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-referential 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;
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" }

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);


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;
say $a;         # OUTPUT: «43␤»

sub f($c is raw) { $c++ }
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, which 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 [email protected], 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

Container 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,])␤»

Although Perl 6 does not prevent you from creating and using self-referential data, by doing so 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 } };

43 Contexts and contextualizers

What are contexts and how to switch 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 in general decide what to do with it, as in the case of the sink context. In general, recognizing an object that is in a certain context will force an implicit coercion by calling a specific method on it.


The sink context is equivalent to what in other languages is called 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; however, sinking will explicitly throw away those values, so use sink only if you want to run a gather statement for the side effects.

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 


This context, and probably all other contexts 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 are only a few digits 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.


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.

put $very-complicated-and-hairy-object; # OUTPUT: something meaningful 

Or when smartmatching to a regular expression:

put 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 [email protected]; # 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, 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>␤»


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: «Cannot use a Buf as a string, but you called the Stringy method on it 

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>␤» 

In general, a context will coerce a variable to a particular type by calling the contextualizer; in the case of mixins, if the context class is mixed in, it will behave in that way.

my $described-number = 1i but 'Unity in complex plane';
put $described-number; # OUTPUT: «Unity in complex plane␤»

but creates a mixin, which endows the complex number with a Str method. put contextualizes it into a string, that is, it calls Str, the string contextualizer, with the result shown above.


This context will force a variable to be interpreted as True or False.

say "Hey" if 7;  # OUTPUT: «Hey␤»
say "Ahoy" if "";

This context appears in expressions such as if or while, and is equivalent to calling so on these values.

say "Hey" if 7.so;          # OUTPUT: «Hey␤» 
 say "Ahoy" if not set().so; # OUTPUT: «Ahoy␤» 

In general, non-zero, non-empty will be converted to True; zero or empty will be equivalent to False. But .so can be defined to return any Boolean value we want, so this is just a rule of thumb.

? and ! are the Boolean context operator and its negation respectively. They will force this context on an object.

say ? 0i;    # OUTPUT: «False␤» 
 say ! :true; # OUTPUT: «False␤» 


There are actually several different list contexts, which are better explained in that page. In general, the list contextualizer is the comma ,

say (3,).^name; # OUTPUT: «List␤»

and the method called in that case is also .list

Any.list.^name;   # OUTPUT: «List␤» 
 say 3.list.^name; # OUTPUT: «List␤» 
 say (^3).list;    # OUTPUT: «(0 1 2)␤» 

44 Control flow

Statements used to control the flow of execution


Perl 6 programs consist 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 example could also be written as:

"Hello"; say "World";


Like many other languages, Perl 6 uses blocks enclosed by { and } to turn a sequence of statements into a single one. 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 is a closure, 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 Perl 6 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␤»


{ 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.

Class bodies behave like simple blocks for any top level expression; same goes to roles and other packages, like grammars (which are actually classes) or modules.

class C { 
     say "I live"; 
     die "I will never live!" 
 my $c = C.new;                              │ 
 # OUTPUT: Fails and writes «I live␤I will never live!␤ 

This block will first run the first statement, and then die printing the second statement. $c will never get a value.


Blocks may have phasers: special labeled blocks that break their execution into phases that run in particular phases. See the page phasers for the details.


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 


The simplest way to run a block asynchronously is by writing start before it:

start { sleep 1; say "done" } 
 say "working"; 
 # working, done 

Note that you need a space between the start and the block. In the example above, the start block is in sink context, since it's not assigned to a variable. From version 6.d, these kind of blocks have an exception handler attached:

start { die "We're dead"; } 
 say "working"; 
 sleep 10; 

This code will print Unhandled exception in code scheduled on thread 4 We're dead in version 6.d, while it will simply get out after waiting for 10 seconds in version 6.c.

The start {...} immediately returns a Promise that can be safely ignored if you are not interested in the result of the block. If you are interested in the final value of the block, you can call the .result method on the returned promise. So:

my $promise = start { sleep 10; 42 }
# ... do other stuff
say "The result is $promise.result()";

If the code inside the block has not finished, the call to .result will wait until it is done.

A start may also be used on a bare statement (without curly braces). This is mainly useful when calling a subroutine / method on an object is the only thing to do asynchronously.

sub get42 { 42 }
my $promise = start get42;
say $promise.result; # OUTPUT: «42␤»

Note that code executed this way does not have access to the special variables $! and $/ of its outer block, but receives new ones, so every asynchronous task has its per-task state.

Thus, try expressions and regex matches executed in the asynchronous task have their per-task state.

'a' ~~ /a/; # $/ is set to 「a」
try die;    # $! is defined now with an anonymous AdHoc exception
# as a code block
await start { say $! }; # OUTPUT: «Nil␤»
await start { say $/ }; # OUTPUT: «Nil␤»
# as a single statement
await start $!.say;     # OUTPUT: «Nil␤»
await start $/.say;     # OUTPUT: «Nil␤»


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"


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"


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, and it topicalizes on the condition, much like given:

with "abc".index("a") { .say }      # prints 0

Similarly to 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;

As with the other chainable constructs, an else completing a with/if..orwith/elsif chain will itself topicalize to the value of the prior (failed) condition's topic (either the topic of with or the final orwith or elsif).

In the case of an else following a with or orwith, topicalizing a value guaranteed to be undefined may seem useless. But it makes for a useful idiom when used in conjunction with operations that may fail, because Failure values are always undefined:

sub may_fail( --> Numeric:D ) { 
   my $value = (^10).pick || fail "Zero is unacceptable"; 
   fail "Odd is also not okay" if $value % 2; 
   return $value; 
 with may_fail() -> $value { # defined, so didn't fail 
   say "I know $value isn't zero or odd." 
 } else { # undefined, so failed, and the Failure is the topic 
   say "Uh-oh: {.exception.message}." 

Note that while topicalizing a Failure marks it handled—so you can use the with/else to proceed safely with execution—it doesn't make the Failure value itself safe. Even within the else clause, if you try to use the value directly, it will result in your else clause itself failing (or, in Rakudo, "promoting" the Failure into a thrown exception).

But as seen above, you can use the methods of a handled Failure object the else topicalizes, such as exception, if you wish to provide diagnostics or interrogate the underlying Exception.


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.

There are other ways to modify their default behavior; they 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 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 affect 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 

Since a successful match will exit the block, the behavior of this piece of code:

$_ = True; 
 my $a; 
     $a = do when .so { "foo" } 
 say $a; # OUTPUT: «(Any)␤» 

is explained since the do block is abandoned before any value is stored or processed. However, in this case:

$_ = False; 
 my $a; 
     $a = do when .so { "foo" } 
 say $a; # OUTPUT: «False␤» 

the block is not abandoned since the comparison is false, so $a will actually get a value.


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;              # OUTPUT «(2 4 6)␤»
my @a = do for 1, 2, 3 { $_ * 2 }; @a.say; # OUTPUT «[2 4 6]␤»
my @b = (for 1, 2, 3 { $_ * 2 }); @b.say;  # OUTPUT: «[2 4 6]␤»

The Empty constant will act as a no-op for a loop:

say "Not here" for Empty; 

Will not do anything. This constant is equivalent to a empty Slip or List.

Undefined values will behave in the same way:

my @array := Empty; 
 .say for @array; 
 say @array; # OUTPUT: «()␤» 

Assigning Empty will effectively undefine an Array, using for over an undefined array will not even enter the loop, as shown, effectively behaving in the same way as above when Empty was used directly.

With hyper and race, the for loop is potentially iterated in parallel. See also the documentation for hyper and race in class Map.

my $primes_h = hyper for ^10_000 -> $number { $number if $number.is-prime }; 
 say $primes_h.elems;   # OUTPUT: «1229␤» 
 say $primes_h.tail: 5; # OUTPUT: «(9931 9941 9949 9967 9973)␤» 

with hyper the order of elements is preserved.

my $primes_r = race for ^10_000 -> $number { $number if $number.is-prime }; 
 say $primes_r.elems; # OUTPUT: «1229␤» 

Unlike hyper, race does not preserve the order of elements.


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];

# 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.

Note that gather/take also work for hashes. The return value is still a Seq but the assignment to a hash in the following example makes it a hash.

my %h = gather { take "foo" => 1; take "bar" => 2};
say %h;                                             # OUTPUT: «{bar => 2, foo => 1}␤»


Emits the invocant into the enclosing supply:

my $supply = supply {
    emit $_ for "foo", 42, .5;
$supply.tap: {
    say "received {.^name} ($_)";

# received Str (foo)
# received Int (42)
# received Rat (0.5)


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.



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 { 
         "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],
    given DateTime.now;
# OUTPUT: «Sa 03.06.2016»


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. 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 {
} while $x < 5;
$x.say; # OUTPUT: «5␤»

repeat {
} while $x < 5;
$x.say; # OUTPUT: «6␤»

repeat while $x < 10 {
$x.say; # OUTPUT: «10␤»

repeat while $x < 10 {
$x.say; # OUTPUT: «11␤»

repeat {
} until $x >= 15;
$x.say; # OUTPUT: «15␤»

repeat {
} until $x >= 15;
$x.say; # OUTPUT: «16␤»

repeat until $x >= 20 {
$x.say; # OUTPUT: «20␤»

repeat until $x >= 20 {
$x.say; # OUTPUT: «21␤»

All these forms may produce a return value the same way loop does.


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. Please check the functions documentation for more information on how return values are handled and produced.


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.


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!␤»


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.


A quietly block will suppress all warnings generated in it.

quietly { warn 'kaput!' };
warn 'still kaput!';
# OUTPUT: «still kaput! [...]␤»

Any warning generated from any routine called from within the block will also be suppressed:

sub told-you { warn 'hey...' };
quietly { told-you; warn 'kaput!' };
warn 'Only telling you now!'
# OUTPUT: «Only telling you now!␤ [...] ␤»


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:

 loop ( my $i = 1; True; $i++ ) { 
     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; 


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".

If the NEXT phaser is present, it runs before the next iteration:

my Int $i = 0; 
 while ($i < 10) { 
   if ($i % 2 == 0) { 
   say "$i is odd."; 
   NEXT { 
 # OUTPUT: «1 is odd.␤3 is odd.␤5 is odd.␤7 is odd.␤9 is odd.␤» 

In a whenever block, next immediately exits the block for the current value:

react {
    whenever Supply.interval(1) {
        next if .is-prime;
        say $_;
        done if $_ == 4;

prints "0", "1" and "4" - integers from 0 to 4 with primes skipped.

*Since version 6.d, the next command in a loop that collects its last statement values returns Empty for the iterations they run on.*


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".

If the LAST phaser is present, it runs before exiting the loop:

my Int $i = 1; 
 while ($i < 10) { 
   if ($i % 5 == 0) { 
   LAST { 
     say "The last number was $i."; 
   NEXT { 
 # OUTPUT: «The last number was 5.␤» 

*Since version 6.d, the last command in a loop that collects its last statement values returns Empty for the iterations they run on.*


The redo command restarts the loop block without evaluating the conditional again.

loop { 
     my $x = prompt("Enter a number"); 
     redo unless $x ~~ /\d+/; 

45 Data structures

How Perl 6 deals with data structures and what we can expect from them

Scalar structures

Some classes do not have any internal structure and to access parts of them, specific methods have to be used. Numbers, strings, and some other monolithic classes are included in that class. They use the $ sigil, although complex data structures can also use it.

my $just-a-number = 7;
my $just-a-string = "8";

There is a Scalar class, which is used internally to assign a default value to variables declared with the $ sigil.

my $just-a-number = 333;
say $just-a-number.VAR.^name; # OUTPUT: «Scalar␤»

Any complex data structure can be scalarized by using the item contextualizer $:

(1, 2, 3, $(4, 5))[3].VAR.^name.say; # OUTPUT: «Scalar␤»

However, this means that it will be treated as such in the context they are. You can still access its internal structure.

(1, 2, 3, $(4, 5))[3][0].say; # OUTPUT: «4␤»

An interesting side effect, or maybe intended feature, is that scalarization conserves identity of complex structures.

for ^2 {
     my @list = (1, 1);
     say @list.WHICH;
} # OUTPUT: «Array|93947995146096␤Array|93947995700032␤»

Every time (1, 1) is assigned, the variable created is going to be different in the sense that === will say it is; as it is shown, different values of the internal pointer representation are printed. However

for ^2 {
  my $list = (1, 1);
  say $list.WHICH
} # OUTPUT: «List|94674814008432␤List|94674814008432␤»

In this case, $list is using the Scalar sigil and thus will be a Scalar. Any scalar with the same value will be exactly the same, as shown when printing the pointers.

Complex data structures

Complex data structures fall in two different broad categories: Positional, or list-like and Associative, or key-value pair like, according to how you access its first-level elements. In general, complex data structures, including objects, will be a combination of b