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

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

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

1 Perl 5 to Perl 6 guide - Overview

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

This page attempts to index 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 won't be).

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 .

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.



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

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

-> Method calls

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

$person->name  # Perl 5 
$   # 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.


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:

# Perl 5 
 my @books = $xml->parse_file($file)          # some comment 
# Perl 6 
 my @books = $xml.parse-file($file)\          # some comment 

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


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.

(See also #Dereferencing).

$ Scalar

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

@ Array

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

% Hash

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

& Sub

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

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

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

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

* Glob

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

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

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

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

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

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

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

And here's just one possible Perl 6 translation:

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

[] Array indexing/slicing

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

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

{} Hash indexing/slicing

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

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

Reference creation

TODO: Rewrite this section to make it clear that the "referencing/ dereferencing" metaphor does not map cleanly to the actual Perl 6 container system, and focus more on how one would translate or replace actual code that uses references in Perl 5.

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.

In Perl 6, anonymous arrays and hashes and subs still return their reference during creation. References to named subs are generated by preceding the sub name with a & sigil. References to existing named variables are generated by item context.

my $aref = [ 1, 2, 9 ];          # Both Perl 5&6 
 my $href = { A => 98, Q => 99 }; # Both Perl 5&6 [*See Note*] 
my $aref =     \@aaa  ; # Perl 5 
my $aref = item(@aaa) ; # Perl 6 
my $href =     \%hhh  ; # Perl 5 
my $href = item(%hhh) ; # Perl 6 
my $sref =     \&foo  ; # Perl 5 
my $sref =      &foo  ; # Perl 6 

NOTE: If one or more values reference the topic variable, $_, the right-hand side of the assignment will be interpreted as a Block, not a Hash:

my @people = [
    %( id => "1A", firstName => "Andy", lastName => "Adams" ),
    %( id => "2B", firstName => "Beth", lastName => "Burke" ),
    # ...

sub lookup-user (Hash $h) { #`(Do something...) $h }

my @names = map {
    my $query = { name => "$_<firstName> $_<lastName>" };
    say $query.^name;      # Block
    say $query<name>;      # ERROR: Type Block does not support associative indexing

    lookup-user($query);   # Type check failed in binding $h; expected Hash but got Block
}, @people;

Instead, you should either:

See Hash assignment for more details.


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, the curly braces are changed to parentheses.

# Perl 5 
     say      ${$scalar_ref}; 
     say      @{$arrayref  }; 
     say keys %{$hashref   }; 
     say      &{$subref    }; 
# Perl 6 
     say      $($scalar_ref); 
     say      @($arrayref  ); 
     say keys %($hashref   ); 
     say      &($subref    ); 

Note that in both Perl 5 and Perl 6, the surrounding curly braces or parentheses can often be omitted, though the omission can reduce readability.

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, we now use the dot operator . for those tasks.

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

In recent versions of Perl 5 (5.20 and later), a new feature allows the use of the arrow operator for dereferencing: see Postfix Dereferencing Such feature corresponds to Perl 6 .list and .hash methods:

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

The "Zen" slice does the same thing:

# Perl 6 
     my @a = $arrayref[]; 
     my %h = $hashref{}; 

See S32/Containers


See S03/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.

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

~~ Smart-match operator

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

& | ^ String Bitwise ops

& | ^ Numeric Bitwise ops

& | ^ Boolean ops

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

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

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

<< >> Numeric shift left|right ops

Replaced by +< and +> .

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

=> Fat comma

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

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

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

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

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

# Perl 5 
 sub get_the_loot { 
     my $loot = shift; 
     my %options = @_; 
     # ... 
 # Note: no curly braces in this sub call 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); 
# Perl 6, original API 
 sub get_the_loot( $loot, *%options ) { # The * means to slurp everything 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); # Note: no curly braces in this API 
 # Perl 6, API changed to specify valid options 
 # The colon before the sigils means to expect a Pair, 
 # 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. Range has many new wrinkles in Perl 6, but 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"

Compound Statements


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 { 
     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 smart-matches on the input value such that lookups using more complex entities such as regexps can be used instead of scalar values.

See also the warnings on the smart-match 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 

do while/until

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

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

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

for foreach

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

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

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

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

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

If the default topic $_ is being used, but needs to be read-write, then just use <-> and explicitly specify $_.

for (@cars)      {...} # Perl 5; $_ is read-write 
for @cars        {...} # Perl 6; $_ is read-only 
 for @cars <-> $_ {...} # Perl 6; $_ is 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 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 ~= ':' 


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. See S05/Substitution.

Captures start with 0, not 1

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

Move modifiers

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

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

Add :P5 or :Perl5 adverb

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

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

Special matchers generally fall under the <> syntax

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

For character classes, this means that:

For lookaround assertions:

For more info see lookahead assertions.

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

Longest token matching (LTM) displaces alternation

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

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

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

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


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

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



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 throw exceptions by default unless you test the return value explicitly.

# 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; # Throws exception on error 
 my $o_fh = open $output_path, :w; # Throws exception on error 



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

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 
 pi, e, i; # built-in constants in Perl 6 


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


Perl pragma to use integer arithmetic instead of floating point


Manipulate @INC at compile time


No longer relevant.

In Perl 6, method calls now always use the C3 method resolution order.


No longer relevant.

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


Discouraged in Perl 5. See

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

Command-line flags

See S19/commandline


-c -e -h -I -n -p -S -T -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" } 
 ./ -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 S19#Removed Syntactic Features.

This is now the default behavior.

File-related operations

Reading the lines of a text file into an array

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

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

In Perl 6, this has been simplified to

my @lines = "file".IO.lines;

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

Trapping the standard output of executables.

Whereas in Perl 5 you would do:

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

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

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

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

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

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

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

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

Environment variables

Perl module library path

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

$ PERL5LIB="/some/module/lib" perl 

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 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 and all subs with this role are then exported. Hence, the following module Bar exports the subs foo and bar but not baz:

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

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

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

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

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

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

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

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

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

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

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

use Bar <foo>; 
 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.

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 = ( 
# Perl 6 
     say [ :$foo, :$bar, :@baz ].perl; 
 # Output 
     ["foo" => 42, "bar" => 44, "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 --file=foo --length=42 --verbose 
     Verbosity on 
 perl --length=abc 
     Value "abc" invalid for option length (number expected) 
     Died at 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.


Larry Wall's own code for translating Perl 5 to Perl 6 has bit-rotted, and is not (currently) viable on recent releases of Perl 5.

MAD (Misc Attribute Definition) is a configuration option when building Perl from a source distribution. The perl executable analyses and translates your Perl sourcecode into an op-tree, and then executes the program by walking the op-tree. Normally, most of the details from the analysis are thrown away during this process. When MAD is enabled, the perl executable will save those details to an XML file, which can then be read and further processed into Perl 6 code by a MAD parser.

Please consult #perl6 to find out the best release of Perl 5 to use for your MAD science experiments.


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

2 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 smart match (~~) 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 smart match:

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

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


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

: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 that mimics the original Perl 5 behaviour 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.


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: { say "five seconds have passed" } + 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 = $;
    $package    = $frame.code.package;
my $file    = $frame.file;
my $line    = $frame.line;

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

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

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


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

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

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

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


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

.head2 chop

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

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

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

.head2 chown

chown is not in Perl 6.


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

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

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

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


Apparently this 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 behaviour 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, but can be also used as a method, i. e. (1/60000).cos.


This appears not to have made it into Perl 6.

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 behaviour 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. may be of some help here, as well as the design document at There is also some information at

The Perl 6 ecosystem has a module P5each which exports an each function that mimics the original Perl 5 behaviour 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.


Replaced by EVAL. 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.)


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, but can also be used as a method: 5.exp;


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

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


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

get and set functions

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

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

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

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

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

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


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

The Perl 6 ecosystem has a module P5localtime which exports a gmtime function that mimics the original Perl 5 behaviour 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.

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

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

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


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

Because of this, it has proven impossible to create a Perl 6 module that would export a sub that would mimic the Perl 5 behaviour.


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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 =; 
 my $sec  = $d.second; # Potentially includes fractional seconds 
 my $min  = $d.minute; 
 my $hour = $d.hour; 
 my $mday = $; # or $; 1..31 
 my $mon  = $d.month; # 1..12 
 my $year = $d.year; 
 my $wday = $; # 1 => Monday, 2 => Tuesday, etc. 
 my $yday = $; # 1..366 

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

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

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


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.


Available in Perl 6, but must have an expression to work on. Also available as a method. I. e. log(2) is equivalent to 2.log.


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 smart match 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 = { $_ * 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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 behaviour 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 behaviour is different in Perl 6: @b.push: @a will push @a into @b as a single element. See also the append method.

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

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


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

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


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

Alas, it is currently (Rakudo 2018.04) not possible to create sub named rand that takes a parameter, so it is impossible to create a module in the ecosystem to support the Perl 5 behaviour.


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


Still available in Perl 6.


No equivalent.


No equivalent.


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.


Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a rewinddir function that mimics the original Perl 5 behaviour 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 behaviour 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 smart match 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 Alternately, you can use a method call: $fh.say("howdy!")

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


Gone. Apparently "very" gone.

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


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

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


Not supported in Perl 6.

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


"[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 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 behaviour 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 behaviour 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 behaviour as much as possible.


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


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


Works as a function and also as a method. sin(2) and 2.sin are equivalent.


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

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

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

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


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)


Works as a function and a method. sqrt(4) and 4.sqrt are equivalent.


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

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 a unpack function that mimics the original Perl 5 behaviour as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.


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

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

The Perl 6 ecosystem has a module P5shift which exports a unshift function that mimics the original Perl 5 behaviour 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 a untie function that mimics the original Perl 5 behaviour 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///.

3 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 detail here. If you need to know the precedence and associativity of a given operator in Perl 6, refer to Operator Precedence.

Terms and List Operators

The things listed in Perl 5's perlop document as unary and list operators in this section tend to be things that can also be thought of as functions, such as print and chdir. As such, you can find information about them in the functions guide. Parentheses are still used for grouping.

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 $ 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) You can get a reference to a named subroutine by using the & sigil: $sref = &foo Anonymous arrays, hashes, and subs return their references during creation right away.

Binding Operators

=~ and !~ have been replaced by ~~ and !~~, respectively. Those of you who consider smart matching broken in Perl 5 will be happy to hear that it works much better in Perl 6, as the stronger typing means less guesswork.

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 smart match operator as in Perl 5, but it's also just the match operator in Perl 6, as noted above. For how smart matching works in Perl 6, see

Smartmatch Operator

See the entry on ~~ directly above.

Bitwise And

Binary & is +& in Perl 6.

Bitwise Or and Exclusive Or

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

C-style Logical And


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

Comma Operator

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

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

List Operators (Rightward)

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

Logical Not

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

Logical And

Lower precedence version of && as in Perl 5.

Logical or and Exclusive Or

or is the low precedence version of ||. The documentation lists an xor, but does not actually document it.

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. E. g. @a = <1 2 3>;say qq/@a[]; results in "1 2 3". Hashes interpolate in a possibly unexpected 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 (apparently). 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 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.


Although it's not specifically documented, 1 while foo(); appears to work in this sense.

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

4 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 probably works similarly in Perl 6 to the way it does in Perl 5. However, as of this writing, it does not seem to be functional. For what is planned for goto, see

The Ellipsis Statement

... (along with !!! and ???) are used to create stub declarations. This is a bit more complicated than the use of ... in Perl 5, so you'll probably want to look at 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

5 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

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

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

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

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

$$ is replaced in Perl 6 by $*PID

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

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

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

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.Numeric, while the username via $*USER.Str.

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

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

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

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

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

For more on placeholder variables, see this page

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

The running version of Perl 6 is kept by $*PERL special variable, that is an object. The running version is retrieved via $*PERL.version, which returns something like v6.c; the full stringified version of the Perl interpreter is obtained via $*PERL.Str, 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 $**.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 ' ~ $ 
         ~ ' by '    ~ $what.auth; 
 # Kernel 
 # version named linux by unknown 
 # Distro 
 # version 17.04.Zesty.Zapus named ubuntu by 
 # 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.

[NEEDS FURTHER RESEARCH] No equivalent variable. S28 indicates that this functionality is dealt with in Perl 6 by event filters and exception translation.

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

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

There is no analog to this in Perl 6.

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

Performance issues

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

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

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

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

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

Replaced by $/.prematch.

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

Replaced by $/.postmatch.

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

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

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

...and possibly

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

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

As with most regular expression related variables, this functionality is, at least in part, moved to the $/ variable in Perl 6. Or, in this case, the numbered variables that alias to the indexes of it. The offset is found by using the .to method. I. e. the first offset is $/[0].to, which is synonymous with $ 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.filename.

@*ARGS contains the command line arguments.

This has been replaced by $*ARGFILES.

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

Currently no obvious equivalent.

No direct replacement exists.

When iterating using lines method from IO::Path or IO::Handle types, you can zip with a Range:

for 1..* Z "foo".IO.lines -> ($ln, $text) { 
     say "$ln: $text" 
 # 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. $*

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

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

Not implemented in Perl 6.

There are no built-in formats in Perl 6.

Error Variables

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

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

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

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

and the above code produces the following output

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

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

Currently no equivalents for either of these variables.

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

No Perl 6 equivalent.

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

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

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

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

Deprecated and removed variables

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

6 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

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 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: 
     my Code $examples = "amazing"; 
 Mind === blown. 
 =head3 Minor details about  My Definition 
 It's fantastic. 
 =head2 And now, for something completely different 

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

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

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

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

Then the results on the rendered page:

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

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

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

renders like this

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

7 Classes and Objects

A tutorial for creating and using classes in Perl 6

More descriptive title?

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 = => => 0, y => 0), upper => => 10, y => 10)); 
 say $r.area(); # OUTPUT: «100␤» 

You can also provide your own construction and build implementation. The following, more elaborate example shows how a dependency handler might look in Perl 6. It showcases custom constructors, private and public attributes, methods and various aspects of signatures. It's not very much 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 
     # BUILD is the equivalent of a constructor in other languages 
     method new(&callback, *@dependencies) { 
         return self.bless(:&callback, :@dependencies); 
     submethod BUILD(:&!callback, :@!dependencies) { } 
     method add-dependency(Task $dependency) { 
         push @!dependencies, $dependency; 
     method perform() { 
         unless $!done { 
             .perform() for @!dependencies; 
             $!done = True; 
 my $eat ={ say 'eating dinner. NOM!' }, { say 'making dinner' }, 
   { say 'buying food' }, 
       { say 'making some money' }), 
       { say 'going to the store' }) 
   { say 'cleaning kitchen' }) 

Starting with class

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

Declaring a class creates a new type object which, by default, is installed into the current package (just like a variable declared with our scope). This type object is an "empty instance" of the class. For example, types such as Int and Str refer to the type object of one of the Perl 6 built-in classes. The example above uses the class name Task so that other code can refer to it later, such as to create class instances by calling the new method.

You can use .DEFINITE method to find out if what you have is an instance or a type object:

say Int.DEFINITE; # OUTPUT: «False␤» (type object)
say 426.DEFINITE; # OUTPUT: «True␤»  (instance)

class Foo {};
say Foo.DEFINITE;     # OUTPUT: «False␤» (type object)
say; # 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!␤»


The first three lines inside the class block all declare attributes (called fields or instance storage in other languages). Just as a my variable cannot be accessed from outside its declared scope, attributes are not accessible outside of the class. This encapsulation is one of the key principles of object oriented design.

The first declaration specifies instance storage for a callback – a bit of code to invoke in order to perform the task that an object represents:

has &!callback; 

The & sigil indicates that this attribute represents something invocable. The ! character is a twigil, or secondary sigil. A twigil forms part of the name of the variable. In this case, the ! twigil emphasizes that this attribute is private to the class.

The second declaration also uses the private twigil:

has Task @!dependencies; 

However, this attribute represents an array of items, so it requires the @ sigil. These items each specify a task that must be completed before the present one can complete. Furthermore, the type declaration on this attribute indicates that the array may only hold instances of the Task class (or some subclass of it).

The third attribute represents the state of completion of a task:

has Bool $.done; 

This scalar attribute (with the $ sigil) has a type of Bool. Instead of the ! twigil, the . twigil is used. While Perl 6 does enforce encapsulation on attributes, it also saves you from writing accessor methods. Replacing the ! with a . both declares the attribute $!done and an accessor method named done. It's as if you had written:

has Bool $!done;
method done() { return $!done }

Note that this is not like declaring a public attribute, as some languages allow; you really get both a private attribute and a method, without having to write the method by hand. You are free instead to write your own accessor method, if at some future point you need to do something more complex than return the value.

Note that using the . twigil has created a method that will provide read-only access to the attribute. If instead the users of this object should be able to reset a task's completion state (perhaps to perform it again), you can change the attribute declaration:

has Bool $.done is rw;

The is rw trait causes the generated accessor method to return something external code can modify to change the value of the attribute.

You can also supply default values to attributes (which works equally for those with and without accessors):

has Bool $.done = False;

The assignment is carried out at object build time. The right-hand side is evaluated at that time, and can even reference earlier attributes:

has Task @!dependencies; 
 has $.ready = not @!dependencies; 

Static fields?

Perl 6 has no static keyword. Nevertheless, any class may declare anything that a module can, so making a scoped variable sounds like good idea.

class Singleton { 
     my Singleton $instance; 
     method new {!!!} 
     submethod instance { 
         $instance = Singleton.bless unless $instance; 

Class attributes defined by my or our may also be initialized when being declared, however we are implementing the Singleton pattern here and the object must be created during its first use. It is not 100% possible to predict the moment when attribute initialization will be executed, because it can take place during compilation, runtime or both, especially when importing the class using the use keyword.

class HaveStaticAttr { 
       my Foo $.foo = some_complicated_subroutine; 

Class attributes may also be declared with a secondary sigil – in a similar manner to object attributes – that will generate read-only accessors if the attribute is to be public.


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 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;
}; # 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 ={ 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 ={ say 'eating dinner. NOM!' }, { say 'making dinner' }, 
   { say 'buying food' }, 
       { say 'making some money' }), 
       { say 'going to the store' }) 
   { say 'cleaning kitchen' }) 

Notice how the custom constructor and sensible use of whitespace makes task dependencies clear.

Finally, the perform method call recursively calls the perform method on the various other dependencies in order, giving the output:

making some money 
 going to the store 
 buying food 
 cleaning kitchen 
 making dinner 
 eating dinner. NOM! 


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

if $o ~~ Employee { say "It's an employee" }; 
 if $o ~~ GeekCook { say "It's a geeky cook" }; 
 say $o.WHAT; 
 say $o.perl; 
 say $o.^methods(:local)».name.join(', '); 
 say $o.^name; 

The output can look like this:

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

The first two tests each smart-match 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.^{ $_.^name }).join(', '); 

Finally $o.^name calls the name method on the meta object, which unsurprisingly returns the class name.

Introspection is very useful for debugging and for learning the language and new libraries. When a function or method returns an object you don't know about, finding its type with .WHAT, seeing a construction recipe for it with .perl, and so on, you'll get a good idea of what its return value is. With .^methods you can learn what you can do with the class.

But there are other applications too: a routine that serializes objects to a bunch of bytes needs to know the attributes of that object, which it can find out via introspection.

Overriding default gist method

Some classes might need its own version of gist, which overrides the terse way it is printed when called to provide a default representation of the class. For instance, exceptions might want to write just the payload and not the full object so that it is clearer what has happened. But you can do that with every class:

class Cook { 
     has @.utensils  is rw; 
     has @.cookbooks is rw; 
     method cook( $food ) { 
         return "Cooking $food"; 
     method clean_utensils { 
         return "Cleaning $_" for @.utensils; 
     multi method gist(Cook:U:) { '⚗' ~ self.^name ~ '⚗' } 
     multi method gist(Cook:D:) { '⚗ Cooks with ' ~ @.utensils.join( " ‣ ") ~ ' using ' ~ "«" ~ * ~ "»").join( " and ") } 
 my $cook = 
     utensils => <spoon ladle knife pan>, 
     cookbooks => ['Cooking for geeks','The French Chef Cookbook']); 
 say Cook.gist; # OUTPUT: «⚗Cook⚗» 
 say $cook.gist; # OUTPUT: «⚗ Cooks with spoon ‣ ladle ‣ knife ‣ pan using «Cooking for geeks» and «The French Chef Cookbook»␤» 

Usually you will want to define two methods, one for the class and another for instances; in this case, the class method uses the alembic symbol, and the instance method, defined below, aggregates the data we have on the cook to show it in a narrative way.

8 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

There is a large presence on the #perl6 channel on, who are happy to provide support and answer questions. More resources can be found in the community page. Camelia, the multi-color butterfly with P 6 in her wings, is the symbol of this diverse and welcoming community. We use extensively the #perl6 IRC channel for communication, questions and simply hanging out. Check out this IRC lingo resource for the abbreviations frequently used there. StackOverflow is also a great resource for asking questions and helping others with their Perl 6 problems and challenges.

Perl 6 weekly

Wendy posts in her blog "Perl 6 weekly" a summary of Perl 6 posts, tweets, and comments. Best single resource to know what is going on in the Perl community.

Perl 6 Advent calendar

The Perl 6 community publishes every December an Advent Calendar, with Perl 6 tutorials every day until Christmas. Organization and assignment of days is done through the different Perl 6 channels and the Perl6/mu repository. If you want to participate, it starts organization by the end of October, so check out the channels above for that.

9 Concurrency

Concurrency and Asynchronous Programming

In common with most modern programming languages, Perl 6 is designed to support paralellism, 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 =; 
 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 =; 
 $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 =;
my $promise2 = $promise1.then(
    -> $v { say $v.result; "Second Result" }
$promise1.keep("First Result");
say $promise2.result;   # OUTPUT: «First Result␤Second Result␤»

Here the then method schedules code to be executed when the first Promise is kept or broken, itself returning a new Promise which will be kept with the result of the code when it is executed (or broken if the code fails). keep changes the status of the promise to Kept setting the result to the positional argument. result blocks the current thread of execution until the promise is kept or broken, if it was kept then it will return the result (that is the value passed to keep), otherwise it will throw an exception based on the value passed to break. The latter behaviour is illustrated with:

my $promise1 =;
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 =;
my $promise2 = $promise1.then(-> $v { say $v.status; 'Second Result' });
say $promise2.result;

The method in creates a new promise and schedules a new task to call keep on it no earlier than the supplied number of seconds, returning the new Promise object.

A very frequent use of promises is to run a piece of code, and keep the promise once it returns successfully, or break it when the code dies. The start method provides a shortcut for that:

my $promise = Promise.start(
    { my $i = 0; for 1 .. 10 { $i += $_ }; $i}
say $promise.result;    # OUTPUT: «55␤»

Here the result of the promise returned is the value returned from the code. Similarly if the code fails (and the promise is thus broken), then cause will be the Exception object that was thrown:

my $promise = Promise.start({ die "Broken Promise" });
try $promise.result;
say $promise.cause;

This is considered to be such a commonly required pattern that it is also provided as subroutines:

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

await is almost equivalent to calling result on the promise object returned by start but it will also take a list of promises and return the result of each:

my $p1 = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
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 =;
    my $vow = $promise.vow;{$vow.keep});

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

react and whenever

This could also be written using the react keyword:

react {
    whenever Supply.interval(2) -> $v {
        say $v;
        done() if $v == 4;

Here the whenever keyword uses .act to create a tap on the Supply from the provided block. The react block is exited when done() is called in one of the taps. Using last to exit the block would produce an error indicating that it's not really a loop construct.

A second argument can be supplied to interval which specifies a delay in seconds before the first event is fired. Each tap of a supply created by interval has its own sequence starting from 0, as illustrated by the following:

my $supply = Supply.interval(2);
$supply.tap(-> $v { say "First $v" });
sleep 6;
$supply.tap(-> $v { say "Second $v"});
sleep 10;

An on-demand Supply can also be created from a list of values that will be emitted in turn, thus the first on-demand example could be written as:

react {
    whenever Supply.from-list(1..10) -> $v {
        say $v;

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

An existing supply object can be filtered or transformed, using the methods grep and map respectively, to create a new supply in a manner like the similarly named list methods: grep returns a supply such that only those events emitted on the source stream for which the grep condition is true is emitted on the second supply:

my $supplier =;
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 =;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "Original : $v" });
my $half_supply = ${ $_ / 2 });
$half_supply.tap(-> $v { say "Half : $v" });
for 0 .. 10 {

If you need to have an action that runs when the supply finishes, you can do so by setting the done and quit options in the call to tap:

$supply.tap: { ... }, 
     done => { say 'Job is done.' }, 
     quit => { 
         when X::MyApp::Error { say "App Error: ", $_.message } 

The quit block works very similar to a CATCH. If the exception is marked as seen by a when or default block, the exception is caught and handled. Otherwise, the exception continues to up the call tree (i.e., the same behavior as when quit is not set).

If you are using the react or supply block syntax with whenever, you can add phasers within your whenever blocks to handle the done and quit messages from the tapped supply:

react { 
     whenever $supply { 
         ...; # your usual supply tap code here 
         LAST { say 'Job is done.' } 
         QUIT { when X::MyApp::Error { say "App Error: ", $_.message } } 

The behavior here is the same as setting done and quit on tap.


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

# 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 {$*}";

# Wait 3 seconds before closing the channel { $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 =; 
 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 =;
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 ='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 =, '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 = => { 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 =;

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.

10 Containers

A low-level explanation of Perl 6 containers

This article started as a conversation on IRC explaining the difference between the Array and the List type in Perl 6. It explains the levels of indirection involved in dealing with variables and container elements.

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 run time, 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" }
callable( ⅓ );
callable( 3 );

The sigil has to be provided when referring to the value stored in the container. This in turn allows Routines to be uses 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; it is created by the comma operator.

say (1, 2, 3).^name;    # OUTPUT: «List␤»

A list is immutable, which means you cannot change the number of elements in a list. But if one of the elements happens to be a scalar container, you can still assign to it:

my $x = 42;
($x, 1, 2)[0] = 23;
say $x;                 # OUTPUT: «23␤»
($x, 1, 2)[1] = 23;     # Cannot modify an immutable value
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»

So the list doesn't care about whether its elements are values or containers, they just store and retrieve whatever was given to them.

Lists can also be lazy; in that case, elements at the end are generated on demand from an iterator.

An Array is just like a list, except that it forces all its elements to be containers, which means that you can always assign to elements:

my @a = 1, 2, 3;
@a[0] = 42;
say @a;         # OUTPUT: «[42 2 3]␤»

@a actually stores three scalar containers. @a[0] returns one of them, and the assignment operator replaces the integer value stored in that container with the new one, 42.

Assigning and binding to array variables

Assignment to a scalar variable and to an array variable both do the same thing: discard the old value(s), and enter some new value(s).

Nevertheless, it's easy to observe how different they are:

my $x = 42; say $x.^name;   # OUTPUT: «Int␤»
my @a = 42; say @a.^name;   # OUTPUT: «Array␤»

This is because the Scalar container type hides itself well, but Array makes no such effort. Also assignment to an array variable is coercive, so you can assign a non-array value to an array variable.

To place a non-Array into an array variable, binding works:

my @a := (1, 2, 3);
say @a.^name;               # OUTPUT: «List␤»

Binding to array elements

As a curious side note, Perl 6 supports binding to array elements:

my @a = (1, 2, 3);
@a[0] := my $x;
$x = 42;
say @a;                     # OUTPUT: «[42 2 3]␤»

If you've read and understood the previous explanations, it is now time to wonder how this can possibly work. After all, binding to a variable requires a lexpad entry for that variable, and while there is one for an array, there aren't lexpad entries for each array element, because you cannot expand the lexpad at run time.

The answer is that binding to array elements is recognized at the syntax level and instead of emitting code for a normal binding operation, a special method (called BIND-KEY) is called on the array. This method handles binding to array elements.

Note that, while supported, one should generally avoid directly binding uncontainerized things into array elements. Doing so may produce counter-intuitive results when the array is used later.

my @a = (1, 2, 3);
@a[0] := 42;         # This is not recommended, use assignment instead.
my $b := 42;
@a[1] := $b;         # Nor is this.
@a[2] = $b;          # ...but this is fine.
@a[1, 2] := 1, 2;    # runtime error: X::Bind::Slice
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Array slice␤»

Operations that mix Lists and Arrays generally protect against such a thing happening accidentally.

Flattening, items and containers

The % and @ sigils in Perl 6 generally indicate multiple values to an iteration construct, whereas the $ sigil indicates only one value.

my @a = 1, 2, 3;
for @a { };         # 3 iterations
my $a = (1, 2, 3);
for $a { };         # 1 iteration

@-sigiled variables do not flatten in list context:

my @a = 1, 2, 3;
my @b = @a, 4, 5;
say @b.elems;               # OUTPUT: «3␤»

There are operations that flatten out sublists that are not inside a scalar container: slurpy parameters (*@a) and explicit calls to flat:

my @a = 1, 2, 3;
say (flat @a, 4, 5).elems;  # OUTPUT: «5␤»

sub f(*@x) { @x.elems };
say f @a, 4, 5;             # OUTPUT: «5␤»

You can also use | to create a Slip, introducing a list into the other.

my @l := 1, 2, (3, 4, (5, 6)), [7, 8, (9, 10)];
say (|@l, 11, 12); # OUTPUT: «(1 2 (3 4 (5 6)) [7 8 (9 10)] 11 12)␤»
say (flat @l, 11, 12) # OUTPUT: «(1 2 3 4 5 6 7 8 (9 10) 11 12)␤»

In the first case, every element of @l is slipped as the corresponding elements of the resulting list. flat, in the other hand, flattens all elements including the elements of the included array, except for (9 10).

As hinted above, scalar containers prevent that flattening:

sub f(*@x) { @x.elems };
my @a = 1, 2, 3;
say f $@a, 4, 5;            # OUTPUT: «3␤»

The @ character can also be used as a prefix to coerce the argument to a list, thus removing a scalar container:

my $x = (1, 2, 3);
.say for @$x;               # 3 iterations

However, the <> 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);
$*.say);              # 3 iterations

maps over a list of three elements, not of one.

Self-Referential Data

Containers types, including Array and Hash, allow you to create self-referential structures.

my @a;
@a[0] = @a;
put @a.perl;
# OUTPUT: «((my @Array_75093712) = [@Array_75093712,])␤»

Perl 6 does not prevent you from creating and using self-referential data; You may end up in a loop trying to dump the data; as a last resort, you can use Promises to handle timeouts.

Type Constraints

Any container can have a type constraint in the form of a type object or a subset. Both can be placed between a declarator and the variable name or after the trait of. The constraint is a property of the variable, not the container.

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 there the binding is 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)␤»

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
        FETCH => method () { $c-value },
        STORE => method (T $new-value) {
   => '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 } };

11 Contexts and contextualizers

What are contexts and how to get into them.

A context is needed, in many occasions, to interpret the value of a container. In Perl 6, we will use context to coerce the value of a container into some type or class, or decide what to do with it, as in the case of the sink context.


Sink is equivalent to void context, that is, a context in which we throw (down the sink, as it were) the result of an operation or the return value from a block. In general, this context will be invoked in warnings and errors when a statement does not know what to do with that value.

my $sub = -> $a { return $a² }; 
 $sub; # OUTPUT: «WARNINGS:␤Useless use of $sub in sink context (line 1)␤» 

You can force that sink context on Iterators, by using the sink-all method. Procs can also be sunk via the sink method, forcing them to raise an exception and not returning anything.

In general, blocks will warn if evaluated in sink context; however, gather/take blocks are explicitly evaluated in sink context, with values returned explicitly using take.

In sink context, an object will call its `sink` method if present:

sub foo { 
     return [<a b c>] does role { 
         method sink { say "sink called" } 
 # OUTPUT: sink called 


This context, and probably all of them except sink above, are conversion or interpretation contexts in the sense that they take an untyped or typed variable and duck-type it to whatever is needed to perform the operation. In some cases that will imply a conversion (from Str to Int, for instance); in other cases simply an interpretation (IntStr will be interpreted as Int or as Str).

Number context is called whenever we need to apply a numerical operation on a variable.

my $not-a-string="1                 "; 
 my $neither-a-string="3                        "; 
 say $not-a-string+$neither-a-string; # OUTPUT: «4␤» 

In the code above, strings will be interpreted in numeric context as long as there is only some numbers and no other characters. It can have any number of leading or trailing whitespace, however.

Numeric context can be forced by using arithmetic operators such as + or -. In that context, the Numeric method will be called if available and the value returned used as the numeric value of the object.

my $t = True; 
 my $f = False; 
 say $t+$f;      # OUTPUT: «1␤» 
 say $t.Numeric; # OUTPUT: «1␤» 
 say $f.Numeric; # OUTPUT: «0␤» 
 my $list= <a b c>; 
 say True+$list; # OUTPUT: «4␤» 

In the case of listy things, the numeric value will be in general equivalent to .elems; in some cases, like Thread it will return an unique thread identifier.


In a string context, values can be manipulated as strings. This context is used, for instance, for printing values to standard output.

say $very-complicated-and-hairy-object; # OUTPUT: something meaningful

Or when smart-matching to a regular expression:

p6: say 333444777 ~~ /(3+)/; # OUTPUT: «「333」␤ 0 => 「333」␤»

In general, the Str routine will be called on a variable to contextualize it; since this method is inherited from Mu, it is always present, but it is not always guaranteed to work. In some core classes it will issue a warning.

~ is the (unary) string contextualizer. As an operator, it concatenates strings, but as a prefix operator it becomes the string context operator.

my @array = [ [1,2,3], [4,5,6]]; 
 say ~@array; # OUTPUT: «1 2 3 4 5 6␤» 

12 Control Flow

Statements used to control the flow of execution


Perl 6 programs consists of one or more statements. Simple statements are separated by semicolons. The following program will say "Hello" and then say "World" on the next line.

say "Hello";
say "World";

In most places where spaces appear in a statement, and before the semicolon, it may be split up over many lines. Also, multiple statements may appear on the same line. It would be awkward, but the above could also be written as:

"Hello"; say "World";


Like many languages, Perl 6 uses blocks enclosed by { and } to turn multiple statements into a single statement. It is ok to skip the semicolon between the last statement in a block and the closing }.

{ say "Hello"; say "World" }

When a block stands alone as a statement, it will be entered immediately after the previous statement finishes, and the statements inside it will be executed.

say 1;                    # OUTPUT: «1␤»
{ say 2; say 3 };         # OUTPUT: «2␤3␤»
say 4;                    # OUTPUT: «4␤»

Unless it stands alone as a statement, a block simply creates a closure. The statements inside are not executed immediately. Closures are another topic and how they are used is explained elsewhere. For now it is just important to understand when blocks run and when they do not:

say "We get here"; { say "then here." }; { say "not here"; 0; } or die; 

In the above example, after running the first statement, the first block stands alone as a second statement, so we run the statement inside it. The second block does not stand alone as a statement, so instead, it makes an object of type Block but does not run it. Object instances are usually considered to be true, so the code does not die, even though that block would evaluate to 0, were it to be executed. The example does not say what to do with the Block object, so it just gets thrown away.

Most of the flow control constructs covered below are just ways to tell perl6 when, how, and how many times, to enter blocks like that second block.

Before we go into those, an important side-note on syntax: If there is nothing (or nothing but comments) on a line after a closing curly brace where you would normally put semicolon, then you do not need the semicolon:

# All three of these lines can appear as a group, as is, in a program
{ 42.say }                # OUTPUT: «42␤»
{ 43.say }                # OUTPUT: «43␤»
{ 42.say }; { 43.say }    # OUTPUT: «42␤43␤»


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


The simplest way to run a block where it cannot be a stand-alone statement is by writing do before it:

# This dies half of the time 
 do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win."; 

Note that you need a space between the do and the block.

The whole do {...} evaluates to the final value of the block. The block will be run when that value is needed in order to evaluate the rest of the expression. So:

False and do { 42.say };

...will not say 42. However, the block is only evaluated once each time the expression it is contained in is evaluated:

# This says "(..1 ..2 ..3)" not "(..1 ...2 ....3)"
my $f = "."; say do { $f ~= "." } X~ 1, 2, 3;

In other words, it follows the same reification rules as everything else.

Technically, do is a loop which runs exactly one iteration.

A do may also be used on a bare statement (without curly braces) but this is mainly just useful for avoiding the syntactical need to parenthesize a statement if it is the last thing in an expression:

3, do if 1 { 2 }  ; # OUTPUT: «(3, 2)␤» 
 3,   (if 1 { 2 }) ; # OUTPUT: «(3, 2)␤» 
3,    if 1 { 2 }  ; # Syntax error 

...which brings us to if.


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. In addition, it topicalizes on the condition, much like given:

with "abc".index("a") { .say }      # prints 0

Instead of elsif, orwith may be used to chain definedness tests:

# The below code says "Found a at 0"
my $s = "abc";
with   $s.index("a") { say "Found a at $_" }
orwith $s.index("b") { say "Found b at $_" }
orwith $s.index("c") { say "Found c at $_" }
else                 { say "Didn't find a, b or c" }

You may intermix if-based and with-based clauses.

# This says "Yes"
if 0 { say "No" } orwith Nil { say "No" } orwith 0 { say "Yes" };

As with unless, you may use without to check for undefinedness, but you may not add an else clause:

my $answer = Any;
without $answer { warn "Got: $_" }

There are also with and without statement modifiers:

my $answer = (Any, True).roll;
say 42 with $answer;
warn "undefined answer" without $answer;


The when block is similar to an if block and either or both can be used in an outer block, they also both have a "statement modifier" form. But there is a difference in how following code in the same, outer block is handled: When the when block is executed, control is passed to the enclosing block and following statements are ignored; but when the if block is executed, following statements are executed. (Note there are other ways to modify the default behavior of each which are discussed in other sections.) The following examples should illustrate the if or when block's default behavior assuming no special exit or other side effect statements are included in the if or when blocks:

     if X {...} # if X is true in boolean context, block is executed 
     # following statements are executed regardless 
     when X {...} # if X is true in boolean context, block is executed 
                  # and control passes to the outer block 
     # following statements are NOT executed 

Should the if and when blocks above appear at file scope, following statements would be executed in each case.

There is one other feature a when has that if doesn't: the when's boolean context test defaults to $_ ~~ while the if's does not. That has an effect on how one uses the X in the when block without a value for $_ (it's Any in that case and Any smart matches on True: Any ~~ True yields True). Consider the following:

     my $a = 1; 
     my $b = True; 
     when $a    { say 'a' }; # no output 
     when so $a { say 'a' }  # a (in "so $a" 'so' coerces $a to Boolean context True 
                             # which matches with Any) 
     when $b    { say 'b' }; # no output (this statement won't be run) 

Finally, when's statement modifier form does not effect execution of following statements either inside or outside of another block:

say "foo" when X; # if X is true statement is executed 
                   # following statements are not affected 


The for loop iterates over a list, running the statements inside a block once on each iteration. If the block takes parameters, the elements of the list are provided as arguments.

my @foo = 1..3;
for @foo { $_.print } # prints each value contained in @foo
for @foo { .print }   # same thing, because .print implies a $_ argument
for @foo { 42.print } # prints 42 as many times as @foo has elements

Pointy block syntax or a placeholder may be used to name the parameter, of course.

my @foo = 1..3;
for @foo -> $item { print $item }
for @foo { print $^item }            # same thing

Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.

my @foo = 1..3;
for @foo.kv -> $idx, $val { say "$idx: $val" }
my %hash = <a b c> Z=> 1,2,3;
for %hash.kv -> $key, $val { say "$key => $val" }
for 1, 1.1, 2, 2.1 { say "$^x < $^y" }  # says "1 < 1.1" then says "2 < 2.1"

Parameters of a pointy block can have default values, allowing to handle lists with missing elements.

my @list = 1,2,3,4;
for @list -> $a, $b = 'N/A', $c = 'N/A' {
    say "$a $b $c"
# OUTPUT: «1 2 3␤4 N/A N/A␤»

If the postfix form of for is used a block is not required and the topic is set for the statement list.

say „I $_ butterflies!“ for <♥ ♥ ♥>;
# OUTPUT«I ♥ butterflies!␤I ♥ butterflies!␤I ♥ butterflies!␤»

A for may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:

for $*IN.lines -> $line { .say } 

Iteration variables are always lexical, so you don't need to use my to give them the appropriate scope. Also, they are read-only aliases. If you need them to be read-write, use <-> instead of ->. If you need to make $_ read-write in a for loop, do so explicitly.

my @foo = 1..3;
for @foo <-> $_ { $_++ }

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:

(for 1, 2, 3 { $_ * 2 }).say;              # says "(2 4 6)"
my @a = do for 1, 2, 3 { $_ * 2 }; @a.say; # says "[2 4 6]"
my @b = (for 1, 2, 3 { $_ * 2 }); @a.say;  # same thing


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


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 smart match 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],
# 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, for now. It would probably be best to use eager to guarantee that a loop whose return value may be used actually runs:

sub heads-in-a-row {
    (eager loop (; 2.rand < 1;) { "heads".say })

while, until

The while statement executes the block as long as its condition is true. So

my $x = 1;
while $x < 4 {
    print $x++;
print "\n";

# OUTPUT: «123␤»

Similarly, the until statement executes the block as long as the expression is false.

my $x = 1;
until $x > 3 {
    print $x++;
print "\n";

# OUTPUT: «123␤»

The condition for while or until can be parenthesized, but there must be a space between the keyword and the opening parenthesis of the condition.

Both while and until can be used as statement modifiers. E. g.

my $x = 42;
$x-- while $x > 12

Also see repeat/while and repeat/until below.

All these forms may produce a return value the same way loop does.

repeat/while, repeat/until

Executes the block at least once and, if the condition allows, repeats that execution. This differs from while/until in that the condition is evaluated at the end of the loop, even if it appears at the front.

my $x = -42;
repeat {
} 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.

TODO add link to section in /language/function that shows how return values are produces/handled


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: « …

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

quietly { warn 'kaput!' };
warn 'still kaput!';
# OUTPUT: «still kaput! [...]␤»


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


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


The redo command restarts the loop block without evaluating the conditional again.

loop { 
     my $x = prompt("Enter a number"); 
     redo unless $x ~~ /\d+/; 

13 Enumeration

Using the enum type

An example using the enum type

In Perl 6 the enum type is much more complex than in some other languages, and the details are found in its type description here: enum.

This short document will give a simple example of its use similar to use in C-like languages.

Say we have a program that needs to write to various directories so we want a function that, given a directory name, tests it for (1) its existence and (2) whether it can be written to by the user of the program. The results of the test will determine what actions the program takes next.

# the directory will have one of these three statuses from the user's perspective: 
 enum DirStat <CanWrite NoDir NoWrite>; 
 sub check-dir-status($dir --> DirStat) { 
     if $dir.IO.d { 
         # dir exists, can the program user write to it? 
         my $f = "$dir/.tmp"; 
         spurt $f, "some text"; 
         CATCH { 
             # unable to write for some reason 
             return NoWrite; 
         # if we get here we must have successfully written to the dir 
         unlink $f; 
         return CanWrite; 
     # if we get here the dir must not exist 
     return NoDir; 
 # test each of three directories by a non-root user 
 my $dirs = 
     '/tmp',  # normally writable by any user 
     '/',     # writable only by root 
     '~/tmp'; # a non-existent dir in the user's home dir 
 for $dirs -> $dir { 
     my $stat = check-dir-status $dir; 
     say "status of dir '$dir': $stat"; 
     if $stat ~~ CanWrite { 
         say "  user can write to dir: $dir"; 
 # output 
 #   status of dir '/tmp': CanWrite 
 #     user can write to dir: /tmp 
 #   status of dir '/': NoWrite 
 #   status of dir '~/tmp': NoDir 

14 Exceptions

Using exceptions in Perl 6

Exceptions in Perl 6 are objects that hold information about errors. An error can be, for example, the unexpected receiving of data or a network connection no longer available, or a missing file. The information that an exception objects store is, for instance, a human-readable message about the error condition, the backtrace of the raising of the error, and so on.

All built-in exceptions inherit from Exception, which provides some basic behavior, including the storage of a backtrace and an interface for the backtrace printer.

Ad hoc exceptions

Ad hoc exceptions can be used by calling die with a description of the error:

die "oops, something went wrong";

# RESULT: «oops, something went wrong in block <unit> at my-script.p6:1␤»

It is worth noting that die prints the error message to the standard error $*ERR.

Typed exceptions

Typed exceptions provide more information about the error stored within an exception object.

For example, if while executing .zombie copy on an object, a needed path foo/bar becomes unavailable, then an X::IO::DoesNotExist exception can be raised:

die"foo/bar"), :trying("zombie copy"))

# RESULT: «Failed to find 'foo/bar' while trying to do '.zombie copy'
#          in block <unit> at my-script.p6:1»

Note how the object has provided the backtrace with information about what went wrong. A user of the code can now more easily find and correct the problem.

Catching exceptions

It's possible to handle exceptional circumstances by supplying a CATCH block:

die"foo/bar"), :trying("zombie copy"));

    when X::IO { $*ERR.say: "some kind of IO exception was caught!" }

# RESULT: «some kind of IO exception was caught!»

Here, we are saying that if any exception of type X::IO occurs, then the message some kind of IO exception was caught! will be sent to stderr and displayed.

A CATCH block uses smart matching similar to how given/when smart matches on options, thus it's possible to catch and handle various categories of exceptions inside a when block.

To handle all exceptions, use a default statement. This example prints out almost the same information as the normal backtrace printer.

     default {
         say .payload;
         for .backtrace.reverse {
             next if .file.starts-with('SETTING::');
             next unless .subname;
             say "  in block {.subname} at {.file} line {.line}";

Note that the match target is a role. To allow user defined exceptions to match in the same manner, they must implement the given role. Just existing in the same namespace will look alike but won't match in a CATCH block.

Exception handlers and enclosing blocks.

After a CATCH has handled the exception, the block enclosing the CATCH is exited.

In other words, even when the exception is handled successfully, the rest of the code in the enclosing block will never be executed.

die "something went wrong ...";

    # will definitely catch all the exception
    default { .Str.say; }

say "This won't be said.";   # but this line will be never reached since
                             # the enclosing block will be exited immediately
# OUTPUT: «something went wrong ...␤»

Compare with this:


      default { .Str.say; }

  die "something went wrong ...";


say "Hi! I am at the outer block!"; # OUTPUT: «Hi! I am at the outer block!␤»

See "Resuming of Exceptions", for how to return control back to where the exception originated.


To contain an exception, use a try block. Any exception that is thrown in such a block will be caught by the implicit CATCH block or a CATCH block provided by the user. In the latter case, any unhandled exception will be rethrown.

class E is Exception { method message() { "Just stop already!" } }

try {; # this will be local

    say "This won't be said.";

say "I'm alive!";

try {
    CATCH {
        when X::AdHoc { .Str.say; .resume }

    die "No, I expect you to DIE Mr. Bond!";

    say "I'm immortal.";;

    say "No, you don't!";


I'm alive! 
 No, I expect you to DIE Mr. Bond! 
 I'm immortal. 
 Just stop already! 
   in block <unit> at exception.p6 line 21 

A try-block is a normal block and as such treats its last statement as the return value of itself. We can therefore use it as a right-hand-side.

say try { +"99999" } // "oh no"; 
 say try { +"hello" } // "oh no"; 
 # OUTPUT: «99999␤oh no␤» 

Try blocks support else blocks indirectly by returning the return value of the expression or Nil if an exception was thrown.

with try +"♥" {
    say "this is my number: $_"
} else {
    say "not my number!"
# OUTPUT: «not my number!␤»

try can also be used with a statement instead of a block:

say try "some-filename.txt".IO.slurp // "sane default"; 
 # OUTPUT: «sane default␤» 

Throwing exceptions

Exceptions can be thrown explicitly with the .throw method of an Exception object.

This example throws an AdHoc exception, catches it and allows the code to continue from the point of the exception by calling the .resume method.

    CATCH {
        when X::AdHoc { .resume }



If the CATCH block doesn't match the exception thrown, then the exception's payload is passed on to the backtrace printing mechanism.

    CATCH {  }


# RESULT: «foo
#          in block <unit> at my-script.p6:1»

This next example doesn't resume from the point of the exception. Instead, it continues after the enclosing block, since the exception is caught, and then control continues after the CATCH block.

    CATCH {
        when X::AdHoc { }



throw can be viewed as the method form of die, just that in this particular case, the sub and method forms of the routine have different names.

Resuming of Exceptions

Exceptions interrupt control flow and divert it away from the statement following the statement that threw it. Any exception handled by the user can be resumed and control flow will continue with the statement following the statement that threw the exception. To do so, call the method .resume on the exception object.

CATCH { when X::AdHoc { .resume } }         # this is step 2

die "We leave control after this.";         # this is step 1

say "We have continued with control flow."; # this is step 3

Uncaught Exceptions

If an exception is thrown and not caught, it causes the program to exit with a non-zero status code, and typically prints a message to the standard error stream of the program. This message is obtained by calling the gist method on the exception object. You can use this to suppress the default behavior of printing a backtrace along with the message:

class X::WithoutLineNumber is X::AdHoc {
    multi method gist(X::WithoutLineNumber:D:) {
die => "message")

# prints "message\n" to $*ERR and exits, no backtrace

Control Exceptions

Control exceptions are thrown by certain keywords and are handled either automatically or by the appropriate phaser. Any unhandled control exception is converted to a normal exception.

{ return; CATCH { default { say .^name, ': ',.Str } } }

# OUTPUT: «X::ControlFlow::Return: Attempt to return outside of any Routine␤»
# was CX::Return

15 Experimental Features

New features for brave users

During Perl 6 development, new features are often made available for users to experimental with before their design is completed. Eventually these features may be made part of the Perl 6 specification. To use these features, one uses the experimental pragma in program source code, for example, like this:

use experimental :macros;

Following is a list of current experimental features and a short description of each feature's purpose or a link to more details about its use. (Note: Features marked "[TBD]" are to be defined later.)

The following should be a table but formatting in tables is not yet rendered properly.


The collate and coll methods are no longer experimental. However, they are affected by the $*COLLATION, which configures the four collation levels. While the Primary, Secondary and Tertiary mean different things for different scripts, for the Latin script used in English they mostly correspond with Primary being Alphabetic, Secondary being Diacritics and Tertiary being Case.

In the example below you can see how when we disable tertiary collation which in Latin script generally is for case, and also disable quaternary which breaks any ties by checking the codepoint values of the strings, we get Same back for A and a:

use experimental :collation;
$*COLLATION.set(:quaternary(False), :tertiary(False));
say 'a' coll 'A'; #OUTPUT: «Same␤»
say ('a','A').collate == ('A','a').collate; # OUTPUT: «True␤»

The $*COLLATION API could change at any time, so use it with caution.

16 FAQ

Frequently Asked Questions about Perl 6


What's the difference between Rakudo and Perl 6?

Properly speaking, Rakudo is an implementation of Perl 6. It's currently the most developed, but there have been other implementations in the past and there will likely be others in the future. Perl 6 is the definition of the language. Often, Rakudo and Perl 6 will be used interchangeably.

Has Perl 6 been released?

Yes with the Rakudo 2015.12 implementation version on December 25th 2015.

Is there a Perl 6 version 6.0.0?

No. The first stable language specification version is v6.c ("Christmas"). Future versions of the spec may have point releases (e.g. v6.c.2) or major releases (e.g., v6.d).

Running perl6 -v will display the language version your compiler implements:

$ perl6 -v 
 This is Rakudo version 2017.07 built on MoarVM version 2017.07 
 implementing Perl 6.c. 

When is v6.d going to be released?

Hopefully within a few months. Details at

You can already use some of the new features by using use v6.d.PREVIEW pragma. Also, many of the 6.d features were already implemented in 6.c compiler, due to the lack (at the time) of the infrastructure to support separate language versions. Thus, when 6.d is released, you may find you were already using many of the new features.

As a Perl 6 user, what should I install?

Mac users can use the latest Rakudo Star DMG binary installer at

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

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

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

Be mindful of publication dates when reading third-party articles. Anything published before December, 2015 likely describes pre-release version of Perl 6.

You can always get help from a live human in our help chat or search the chat logs.

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. 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 and I only have!

This is commonly seen on Debian-like systems. You need to install libfoo-dev package, to set a sym link for the missing file.

Where have all the traditional UNIX library functions gone?

It's very easy to use Nativecall to access them.

An ecosystem module POSIX is also available.

Does Rakudo have a core standard library?

Rakudo Star distribution does come with many useful modules.

Rakudo compiler-only release includes only a couple of the most basic modules.

Many more modules can be found in the ecosystem.

Is there something like B::Deparse/How can I get hold of the AST?

Use --target=optimize command line option to view the AST of your program, e.g., perl6 --target=optimize -e 'say "hi"'

The target optimize gives the AST after the static optimizer did its job, while target ast gives the AST before that step. To get the full list of available targets, run perl6 --stagestats -e ""

What is Precompilation?

When you load a module for the first time, Rakudo compiles it into bytecode, and both stores it on disk, and uses the compiled bytecode. On subsequent loads, Rakudo prefers to load the bytecode, because that tends to be significantly faster.

Can I have circular dependencies between modules?

No, you can't have circular dependencies, and you should get Circular module loading detected error if you try it.

Very likely you can accomplish what you are trying to do using roles. Instead of A.pm6 depending on B.pm6 and B.pm6 depending on A.pm6, you can have A-Role.pm6 and B-Role.pm6 and classes in A.pm6 and B.pm6 implement these roles respectively. Then you can depend on A-Role.pm6 and B-Role.pm6 without the need for the circular dependency.

One of the reasons why circular dependencies do not work in Perl 6 is one pass parsing. We have to know what A means when we parse B, and we have to know what B means when we parse A, which is clearly an infinite loop.

Note that Perl 6 has no “1 file = 1 class” limitation, and circular dependencies within a single compilation unit (e.g. file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.

Language Features

How can I dump Perl 6 data structures (like Perl 5 Data::Dumper and similar)?

Typical options are to use say routine that uses gist method that gives the "gist" of the object being dumped. More detailed output can be obtained by calling perl method that typically returns representation in EVAL-able code.

If you're using the rakudo implementation, you can use the rakudo-specific dd routine for dumping, whose output is similar to perl, but with more information.


my $foo = %( foo => 'bar' ); 
 say $foo.perl;   # OUTPUT: «${:foo("bar")}␤» 
 say $foo;        # OUTPUT: «{foo => bar}␤» 
 # non-standard routine available in rakudo implementation: 
 dd $foo;         # OUTPUT: «Hash $foo = ${:foo("bar")}␤» 

There are also several ecosystem modules that provide more control over how data structures are dumped, including support for colored output in.

How can I get command line history in the Perl 6 prompt (REPL)?

Install Linenoise from the ecosystem.

An alternative for UNIX-like systems is to install rlwrap. This can be done on Debian-ish systems by running:

sudo apt-get install rlwrap 

Why is the Rakudo compiler so apologetic?

If SORRY! is present in the output the error is a compile time error otherwise it's runtime.


say 1/0;   # Attempt to divide 1 by zero using div 
sub foo( Int $a, Int $b ) {...} 
 foo(1)     # ===SORRY!=== Error while compiling ... 

What is (Any)?

Any is a top level class most objects inherit from. The Any type object is the default value on variables and parameters without an explicit type constraint, which means you'll likely see (Any) printed when you output a gist of a variable without any value, such as using say routine:

my $foo; 
 say $foo; # OUTPUT: «(Any)␤» 
 my Int $baz; 
 say $baz; # OUTPUT: «(Int)␤» 
 my $bar = 70; 
 say $bar; # OUTPUT: «70␤» 

To test whether a variable has any defined values, see DEFINITE and defined routines. Several other constructs exist that test for definiteness, such as with , orwith , and without statements, //, andthen, notandthen, and orelse operators, as well as type constraint smileys.

What is so?

so is a loose precedence operator that coerces to Bool.

It has the same semantics as the ? prefix operator, just like and is the low-precedence version of &&.

Example usage:

say so 1|2 == 2;    # OUTPUT: «True␤»

In this example, the result of the comparison (which is a Junction), is converted to Bool before being printed.

What are those :D and :U things in signatures?

In Perl 6, classes and other types are objects and pass type checks of their own type.

For example, if you declare a variable

my Int $x = 42;

then not only can you assign integers (that is, instances of class Int) to it, but the Int type object itself:

$x = Int 

If you want to exclude type objects, you can append the :D type smiley, which stands for "definite":

my Int:D $x = 42; 
 $x = Int; 
 # dies with: 
 # Type check failed in assignment to $x; 
 # expected Int:D but got Int 

Likewise, :U constrains to undefined values, that is, type objects.

To explicitly allow either type objects or instances, you can use :_.

What is the --> thing in the signature?

--> is a return constraint, either a type or a definite value.

Example of a type constraint:

sub divide-to-int( Int $a, Int $b --> Int ) {
        return ($a / $b).narrow;

divide-to-int(3, 2)
# Type check failed for return value; expected Int but got Rat

Example of a definite return value:

sub discard-random-number( --> 42 ) { rand }
say discard-random-number;
# OUTPUT: «42␤»

In this case, the final value is thrown away because the return value is already specified.

How can I extract the values from a Junction?

If you want to extract the values (eigenstates) from a Junction, you are probably doing something wrong and should be using a Set instead.

Junctions are meant as matchers, not for doing algebra with them.

If you want to do it anyway, you can abuse autothreading for that:

sub eigenstates(Mu $j) {
    my @states;
    -> Any $s { @states.push: $s }.($j);

say eigenstates(1|2|3).join(', ');
# prints 1, 2, 3 or a permutation thereof

If Str is immutable, how does s/// work? If Int is immutable, how does $i++ work?

In Perl 6, values of many basic types are immutable, but the variables holding them are not. The s/// operator works on a variable, into which it puts a newly created string object. Likewise, $i++ works on the $i variable, not just on the value in it.

Knowing this, you would not try to change a literal string (e.g. like 'hello' ~~ s/h/H/;), but you might accidentally do something equivalent using map as follows.

my @foo = <hello world>.map: { s/h/H/ };

# dies with
# Cannot modify an immutable Str (hello)

my @bar = <hello world>».subst-mutate: 'h', 'H';

# dies with
# Cannot resolve caller subst-mutate(Str: Str, Str);
# the following candidates match the type but require
# mutable arguments: ...

Instead of modifying the original value in place, use a routine or operator that returns a new value:

my @foo = <hello world>.map: { S/h/H/ };  # ['Hello','world']
my @bar = <hello world>».subst: 'h', 'H'; # ['Hello','world']

See the documentation on containers for more information.

What's up with array references and automatic dereferencing? Do I need the @ sigil?

In Perl 6, nearly everything is a reference, so talking about taking references doesn't make much sense. Scalar variables can also contain arrays directly:

my @a = 1, 2, 3;
say @a;                 # OUTPUT: «[1 2 3]␤»
say @a.^name;           # OUTPUT: «Array␤»

my $scalar = @a;
say $scalar;            # OUTPUT: «[1 2 3]␤»
say $scalar.^name;      # OUTPUT: «Array␤»

The big difference is that arrays inside a scalar act as one value in list context, whereas arrays will be happily iterated over.

my @a = 1, 2, 3;
my $s = @a;

for @a { ... }          # loop body executed 3 times
for $s { ... }          # loop body executed only once

my @flat = flat @a, @a;
say @flat.elems;            # OUTPUT: «6␤»

my @nested = flat $s, $s;
say @nested.elems;          # OUTPUT: «2␤»

You can force list context with @( ... ) or by calling the .list method on an expression, and item context with $( ... ) or by calling the .item method on an expression.

Why sigils? Couldn't you do without them?

There are several reasons:

"Type Str does not support associative indexing."

You likely tried to mix string interpolation and key characters, like HTML tags:

my $foo = "abc";
say "$foo<html-tag>";

Perl 6 thinks $foo to be a Hash and <html-tag> to be a string literal hash key. Use a closure to help it to understand you.

my $foo = "abc";
say "{$foo}<html-tag>";

Does Perl 6 have coroutines? What about yield?

Perl 6 has no yield statement like Python does, but it does offer similar functionality through lazy lists. There are two popular ways to write routines that return lazy lists:

# first method, gather/take 
 my @values = gather while have_data() { 
     # do some computations 
     take some_data(); 
     # do more computations 
 # second method, use .map or similar method 
 # on a lazy list 
 my @squares = (1..*).map(-> \x { x² }); 

Why can't I initialize private attributes from the new method, and how can I fix this?

Code like

class A {
    has $!x;
    method show-x {
        say $!x;
} => 5).show-x;

does not print 5. Private attributes are private, which means invisible to the outside. If the default constructor could initialize them, they would leak into the public API.

If you still want it to work, you can add a submethod BUILD that initializes them:

class B {
    has $!x;
    submethod BUILD(:$!x) { }
    method show-x {
        say $!x;
} => 5).show-x;

BUILD is called by the default constructor (indirectly, see Object Construction for more details) with all the named arguments that the user passes to the constructor. :$!x is a named parameter with name x, and when called with a named argument of name x, its value is bound to the attribute $!x.

But don't do that. If the name is public, there is no downside to declaring it that way with $.x since the external view is readonly by default, and you can still access it internally with $!x.

How and why do say, put and print differ?

The most obvious difference is that say and put append a newline at the end of the output, and print does not.

But there's another difference: print and put converts its arguments to a string by calling the Str method on each item passed to, say uses the gist method instead. The gist method, which you can also create for your own classes, is intended to create a Str for human interpretation. So it is free to leave out information about the object deemed unimportant to understand the essence of the object.

Or phrased differently, $obj.Str gives a string representation, $obj.gist a short summary of that object suitable for fast recognition by a human, and $obj.perl gives a Perlish representation from which the object could be re-created.

Example: type objects, also known as "undefined values", stringify to an empty string and warn, whereas the gist method returns the name of the type between parentheses (to indicate there's nothing in that value except the type).

my Date $x;     # $x now contains the Date type object
print $x;       # empty string plus warning
say $x;         # OUTPUT: «(Date)␤»

If you like to show a debugging version of an object, it is probably better to use the rakudo-specific dd routine. It essentially does a $obj.perl and shows that on STDERR rather than STDOUT, so it won't interfere with any "normal" output of your program.

So, say is optimized for casual human interpretation, dd is optimized for casual debugging output and print and put are more generally suitable for producing output.

put is thus a hybrid of print and say; like print, it calls the Str method on the object. And like say, it adds a newline at the end of the output.

What's the difference between token and rule ?

regex, token and rule introduce regexes, but with slightly different semantics.

token implies the :ratchet or :r modifier, which prevents the rule from backtracking.

rule implies both the :ratchet and :sigspace (short :s) modifier, which means a rule doesn't backtrace, and it treats whitespace in the text of the regex as <.ws> calls (i.e., matches whitespace, which is optional except between two word characters). Whitespace at the start of the regex and at the start of each branch of an alternation is ignored.

regex declares a plain regex without any implied modifiers.

What's the difference between die and fail?

die throws an exception.

fail returns a Failure object. (If the caller has declared use fatal; in the calling lexical scope, fail throws an exception instead of returning.)

A Failure is an "unthrown" or "lazy" exception. It's an object that contains the exception, and throws the exception if you try to use the Failure as an ordinary object, or ignore it in sink context.

A Failure returns False from a defined check, and you can extract the exception with the exception method.

What's the difference between Pointer and OpaquePointer?

OpaquePointer is deprecated and has been replaced with Pointer.

You can have colonpairs in identifiers. What's the justification?

Identifiers can include colon pairs, which become part of their name. According to Larry Wall's answer to the issue, We already had the colon pair mechanism available, so it was a no-brainer to use that to extend any name that needs to be able to quote uniquefying but non-standard characters (or other information with a unique stringification to such characters).

How does most people enter Unicode characters?

It depends on the operating system, windowing environment and/or editors. This page on entering Unicode characters specifies how it is done in the most popular operating systems and editors.

Perl 6 Implementation

What Perl 6 Implementations are available?

Currently the best developed is Rakudo (using multiple Virtual Machine backends). Historic implementations include Niecza (.NET) and Pugs (Haskell). Others are listed at Perl 6 Compilers

What language is Rakudo written in?

A short answer is that Rakudo is written almost entirely in Perl 6. A more detailed answer is that Rakudo is written in a mixture of Perl 6 and NQP ("Not Quite Perl"). NQP is a lightweight Perl 6-like environment for virtual machines; it's designed to be a high-level way to create compilers and libraries for virtual machines (such as MoarVM and JVM) using Perl 6 syntax.

What language is NQP written in?

NQP is a mixture of (1) NQP code, (2) whatever language the underlying virtual machine is using, (3) some third-party C and Java libraries, and (4) some bootstrapping files created by earlier runs of the build process.

Is Perl 6 Lisp?

(not (not Nil))

Perl 6 Distribution

When will the next version of Rakudo Star be released?

A Rakudo Star release is produced usually quarterly. See About for more information.

Meta Questions and Advocacy

Why is Perl 6 called Perl?

… As opposed to some other name that didn't imply all the things that the higher number might indicate on other languages.

The short answer is that it was Larry's choice under Rule 1.

The community considers Perl 5 and Perl 6 sister languages - they have a lot in common, address many of the same problem spaces, but Perl 6 is not intended to replace Perl 5. In fact, both languages interoperate with each other.

When will Perl 6 be ready? Is it ready now?

Readiness of programming languages and their compilers is not a binary decision. As the language and the implementations evolve, they grow steadily more usable. Depending on your needs, Perl 6 and its compilers may or may not be ready for you.

That said, version 6.c (Christmas 2015) is the first official release of Perl 6 as a language, along with a validation suite and a compiler that passes it.

Why should I learn Perl 6? What's so great about it?

Perl 6 unifies many great ideas that aren't usually found in other programming languages. While several other languages offer some of these features, none of them offer all.

Please see the feature comparison matrix for an overview of implemented features.

Is Perl 6 fast enough for me?

That depends on what you are doing. Rakudo has been developed with the philosophy of "make it work right then make it work fast". It's fast for some things already but needs work for others. Since Perl 6 provides lots of clues to the JIT that other dynamic languages don't, we think we'll have a lot of headroom for performance improvements.

The following crude benchmarks, with all the usual caveats about such things, show that Perl 6 can be faster than Perl 5 for similar tasks if the big weaponry is included; at the same time, Perl 5 can be faster if only the bare bones are included. Similar situation can be observed when comparing Perl 6 to other languages.

Try it on your system. You may be pleasantly surprised!


# Perl 6 version 
 use v6.c; 
 class Foo { has $.i is rw }; 
 for 1..1_000_000 -> $i { 
     my $obj =; 
     $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; 
# A perl program which works under both perl5 (with perl -Mbigint) 
 # and perl6 
 my ($prev, $current) = (1, 0); 
 for (0..100_000) { 
     ($prev, $current) = ($current, $prev + $current); 
 print $current; 

17 Functions

Functions and Functional Programming in Perl 6

Routines are the smallest means of code reuse in Perl 6. They come in several forms, most notably methods, which belong in classes and roles and are associated with an object; and functions (also called subroutines or subs, for short), which can be called independently of objects.

Subroutines default to lexical (my) scoping, and calls to them are generally resolved at compile time.

Subroutines can have a signature, also called parameter list, which specifies which, if any, arguments the signature expects. It can specify (or leave open) both the number and types of arguments, and the return value.

Introspection on subroutines is provided via Routine.

Defining/Creating/Using Functions


To basic way to create a subroutine is to use the sub declarator followed by an optional identifier:

sub my-func { say "Look ma, no args!" }

The sub declarator returns a value of type Sub that can be stored in any container:

my &c = sub { say "Look ma, no name!" }
c;     # OUTPUT: «Look ma, no name!␤»

my Any:D $f = sub { say 'Still nameless...' }
$f();  # OUTPUT: «Still nameless...␤»

my Code \a = sub { say ‚raw containers don't implement postcircumfix:<( )>‘ };
a.();  # OUTPUT: «raw containers don't implement postcircumfix:<( )>␤»

The declarator sub will declare a new name in the current scope at compile time. As such any indirection has to be resolved at compile time:

constant aname = 'foo';
sub ::(aname) { say 'oi‽' };

This will become more useful once macros are added to Perl 6.

To have the subroutine take arguments, a signature goes between the subroutine's name and its body, in parentheses:

sub exclaim  ($phrase)  { 
     say $phrase  ~  "!!!!" 
 exclaim "Howdy, World"; 

By default, subroutines are lexically scoped. That is, sub foo {...} is the same as my sub foo {...} and is only defined within the current scope.

sub escape($str) { 
     # Puts a slash before non-alphanumeric characters 
     S:g[<-alpha -digit>] = "\\$/" given $str 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 
     sub escape($str) { 
         # Writes each non-alphanumeric character in its hexadecimal escape 
         S:g[<-alpha -digit>] = "\\x[{ $/.ord.base(16) }]" given $str 
     say escape 'foo#bar?' # OUTPUT: «foo\x[23]bar\x[3F]␤» 
 # Back to original escape function 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 

Subroutines don't have to be named. If unnamed, they're called anonymous subroutines.

say sub ($a, $b) { $a ** 2 + $b ** 2 }(3, 4) # OUTPUT: «25␤»

But in this case, it's often desirable to use the more succinct block syntax. Subroutines and blocks can be called in place, as in the example above.

Blocks and Lambdas

Whenever you see something like { $_ + 42 }, -> $a, $b { $a ** $b }, or { $^text.indent($:spaces) }, that's Block syntax. It's used after every if, for, while, etc.

for 1, 2, 3, 4 -> $a, $b {
    say $a ~ $b;
# OUTPUT: «12␤34␤»

They can also be used on their own as anonymous blocks of code.

say { $^a ** 2 + $^b ** 2}(3, 4) # OUTPUT: «25␤»

For block syntax details, see the documentation for the Block type.


The parameters that a function accepts are described in its signature.

sub format (Str $s)  { ... } 
 ->  $a, $b  { ... } 

Details about the syntax and use of signatures can be found in the documentation on the Signature class.

Automatic Signatures

If no signature is provided but either of the two automatic variables @_ or %_ are used in the function body, a signature with *@_ or *%_ will be generated. Both automatic variables can be used at the same time.

sub s { say @_, %_ };
say &s.signature # OUTPUT: «(*@_, *%_)␤»


Arguments are supplied as a comma separated list. To disambiguate nested calls, use parentheses:

sub f(&c){ c() * 2 }; # call the function reference c with empty parameter list
sub g($p){ $p - 2 };
say(g(42), 45);       # pass only 42 to g()

When calling a function, positional arguments should be supplied in the same order as the function's signature. Named arguments may be supplied in any order, but it's considered good form to place named arguments after positional arguments. Inside the argument list of a function call, some special syntax is supported:

sub f(|c){};
f :named(35);     # A named argument (in "adverb" form)
f named => 35;    # Also a named argument
f :35named;       # A named argument using abbreviated adverb form
f 'named' => 35;  # Not a named argument, a Pair in a positional argument
my \c = <a b c>.Capture;
f |c;             # Merge the contents of Capture $c as if they were supplied

Arguments passed to a function are conceptually first collected in a Capture container. Details about the syntax and use of these containers can be found in the documentation on the Capture class.

When using named arguments, note that normal List "pair-chaining" allows one to skip commas between named arguments.

sub f(|c){};
f :dest</tmp/foo> :src</tmp/bar> :lines(512);
f :32x :50y :110z;   # This flavor of "adverb" works, too
f :a:b:c;            # The spaces are also optional.

Return values

Any Block or Routine will provide its last expression as a return value to the caller. If return or return-rw are called their parameter, if any, will become the return value. The default return value is Nil.

sub a { 42 };
sub b { say a };
# OUTPUT: «42␤»

Multiple return values are returned as a list or by creating a Capture. Destructuring can be used to untangle multiple return values.

sub a { 42, 'answer' };
put a.perl;
# OUTPUT: «(42, "answer")␤»

my ($n, $s) = a;
put [$s, $n];
# OUTPUT: «answer 42␤»

sub b { <a b c>.Capture };
put b.perl;
# OUTPUT: «\("a", "b", "c")␤»

Return Type Constraints

Perl 6 has many ways to specify a function's return type:

sub foo(--> Int)      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() returns Int {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() of Int      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
my Int sub foo()      {}; say &foo.returns; # OUTPUT: «(Int)␤» 

Attempting to return values of another type will cause a compilation error.

sub foo() returns Int { "a"; }; foo; # Type check fails 

returns and of are equivalent, and both take only a Type since they are declaring a trait of the Callable. The last declaration is, in fact, a type declaration, which obviously can take only a type. -->, however, can take either undefined or definite values.

Note that Nil and Failure are exempt from return type constraints and can be returned from any routine, regardless of its constraint:

sub foo() returns Int { fail   }; foo; # Failure returned 
 sub bar() returns Int { return }; bar; # Nil returned 


Perl 6 allows for writing several routines with the same name but different signatures. When the routine is called by name, the runtime environment determines the proper candidate and invokes it.

Each candidate is declared with the multi keyword. Dispatch happens depending on the number (arity), type and name of arguments. Consider the following example:

# version 1 
 multi happy-birthday( $name ) { 
     say "Happy Birthday $name !"; 
 # version 2 
 multi happy-birthday( $name, $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 # version 3 
 multi happy-birthday( :$name, :$age, :$title  = 'Mr' ) { 
     say "Happy {$age}th Birthday $title $name !"; 
 # calls version 1 (arity) 
 happy-birthday 'Larry';                        # OUTPUT: «Happy Birthday Larry !␤» 
 # calls version 2 (airty) 
 happy-birthday 'Luca', 40;                     # OUTPUT: «Happy 40th Birthday Luca !␤» 
 # calls version 3 
 # (named arguments win against arity) 
 happy-birthday( age => '50', name => 'John' ); # OUTPUT: «Happy 50th Birthday Mr John !␤» 
 # calls version 2 (arity) 
 happy-birthday( 'Jack', 25 );                  # OUTPUT: «Happy 25th Birthday Jack !␤» 

The first two versions of the happy-birthday sub differs only in the arity (number of arguments), while the third version uses named arguments and is chosen only when named arguments are used, even if the arity is the same of another multi candidate.

When two sub have the same arity, the type of the arguments drive the dispatch; when there are named arguments they drive the dispatch even when their type is the same as another candidate:

multi happy-birthday( Str $name, Int $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 multi happy-birthday( Str $name, Str $title ) { 
     say "Happy Birthdaty $title $name !"; 
 multi happy-birthday( Str :$name, Int :$age ) { 
     say "Happy Birthday $name, you turned $age !"; 
 happy-birthday 'Luca', 40;                 # OUTPUT: «Happy 40th Birthday Luca !␤» 
 happy-birthday 'Luca', 'Mr';               # OUTPUT: «Happy Birthdaty Mr Luca !␤» 
 happy-birthday age => 40, name => 'Luca';  # OUTPUT: «Happy Birthday Luca, you turned 40 !␤» 

Named parameters participate in the dispatch even if they are not provided in the call. Therefore a multi candidate with named parameters will be given precedence.

For more information about type constraints see the documentation for the Signature class.

multi as-json(Bool $d) { $d ?? 'true' !! 'false'; }
multi as-json(Real $d) { ~$d }
multi as-json(@d)      { sprintf '[%s]',', ') }

say as-json( True );                        # OUTPUT: «true␤»
say as-json( 10.3 );                        # OUTPUT: «10.3␤»
say as-json( [ True, 10.3, False, 24 ] );   # OUTPUT: «[true, 10.3, false, 24]␤»

multi without any specific routine type always defaults to a sub, but you can use it on methods as well. The candidates are all the multi methods of the object:

class Congrats {
    multi method congratulate($reason, $name) {
        say "Hooray for your $reason, $name";

role BirthdayCongrats {
    multi method congratulate('birthday', $name) {
        say "Happy birthday, $name";
    multi method congratulate('birthday', $name, $age) {
        say "Happy {$age}th birthday, $name";

my $congrats = does BirthdayCongrats;

$congrats.congratulate('promotion','Cindy'); # OUTPUT: «Hooray for your promotion, Cindy␤»
$congrats.congratulate('birthday','Bob');    # OUTPUT: «Happy birthday, Bob␤»

Unlike sub, if you use named parameters with multi methods, the parameters must be required parameters to behave as expected.

Please note that a non-multi sub or operator will hide multi candidates of the same name in any parent scope or child scope. The same is true for imported non-multi candidates.


proto is a way to formally declare commonalities between multi candidates. It acts as a wrapper that can validate but not modify arguments. Consider this basic example:

proto congratulate(Str $reason, Str $name, |) {*}
multi congratulate($reason, $name) {
   say "Hooray for your $reason, $name";
multi congratulate($reason, $name, Int $rank) {
   say "Hooray for your $reason, $name -- got rank $rank!";

congratulate('being a cool number', 'Fred');     # OK
congratulate('being a cool number', 'Fred', 42); # OK
    congratulate('being a cool number', 42);         # Proto match error 

The proto insists that all multi congratulate conform to the basic signature of two strings, optionally followed by further parameters. The | is an un-named Capture parameter, and allows a multi to take additional arguments. The first two calls succeed, but the third fails (at compile time) because 42 doesn't match Str.

say &congratulate.signature # OUTPUT: «(Str $reason, Str $name, | is raw)␤» 

You can give the proto a function body, and place the {*} where you want the dispatch to be done.

# attempts to notify someone -- False if unsuccessful
proto notify(Str $user,Str $msg) {
   my \hour =;
   if hour > 8 or hour < 22 {
      return {*};
   } else {
      # we can't notify someone when they might be sleeping
      return False;

{*} always dispatches to candidates with the parameters it's called with. Parameter defaults and type coercions will work but are not passed on.

proto mistake-proto(Str() $str, Int $number = 42) {*} 
 multi mistake-proto($str, $number) { say $str.^name } 
 mistake-proto(7, 42);  # OUTPUT: «Int␤» -- not passed on 
mistake-proto('test'); # fails -- not passed on 

Conventions and Idioms

While the dispatch system described above provides a lot of flexibility, there are some conventions that most internal functions, and those in many modules, will follow.

Slurpy Conventions

Perhaps the most important one of these conventions is the way slurpy list arguments are handled. Most of the time, functions will not automatically flatten slurpy lists. The rare exceptions are those functions that don't have a reasonable behavior on lists of lists (e.g., chrs) or where there is a conflict with an established idiom (e.g., pop being the inverse of push).

If you wish to match this look and feel, any Iterable argument must be broken out element-by-element using a **@ slurpy, with two nuances:

This can be achieved by using a slurpy with a + or +@ instead of **:

sub grab(+@a) { "grab $_".say for @a }

which is shorthand for something very close to:

multi sub grab(**@a) { "grab $_".say for @a }
multi sub grab(\a) {
    a ~~ Iterable and a.VAR !~~ Scalar ?? nextwith(|a) !! nextwith(a,)

This results in the following behavior, which is known as the "single argument rule" and is important to understand when invoking slurpy functions:

grab(1, 2);      # OUTPUT: «grab 1␤grab 2␤» 
 grab((1, 2));    # OUTPUT: «grab 1␤grab 2␤» 
 grab($(1, 2));   # OUTPUT: «grab 1 2␤» 
 grab((1, 2), 3); # OUTPUT: «grab 1 2␤grab 3␤» 

This also makes user-requested flattening feel consistent whether there is one sublist, or many:

grab(flat (1, 2), (3, 4));   # OUTPUT: «grab 1␤grab 2␤grab 3␤grab 4␤» 
 grab(flat $(1, 2), $(3, 4)); # OUTPUT: «grab 1 2␤grab 3 4␤» 
 grab(flat (1, 2));           # OUTPUT: «grab 1␤grab 2␤» 
 grab(flat $(1, 2));          # OUTPUT: «grab 1␤grab 2␤» 

It's worth noting that mixing binding and sigilless variables in these cases requires a bit of finesse, because there is no Scalar intermediary used during binding.

my $a = (1, 2);  # Normal assignment, equivalent to $(1, 2) 
 grab($a);        # OUTPUT: «grab 1 2␤» 
 my $b := (1, 2); # Binding, $b links directly to a bare (1, 2) 
 grab($b);        # OUTPUT: «grab 1␤grab 2␤» 
 my \c = (1, 2);  # Sigilless variables always bind, even with '=' 
 grab(c);         # OUTPUT: «grab 1␤grab 2␤» 

Functions are First-Class Objects

Functions and other code objects can be passed around as values, just like any other object.

There are several ways to get hold of a code object. You can assign it to a variable at the point of declaration:

my $square = sub (Numeric $x) { $x * $x }
# and then use it:
say $square(6);    # OUTPUT: «36␤»

Or you can reference an existing named function by using the &-sigil in front of it.

sub square($x) { $x * $x };

# get hold of a reference to the function:
my $func = &square

This is very useful for higher order functions, that is, functions that take other functions as input. A simple one is map, which applies a function to each input element:

sub square($x) { $x * $x };
my @squared = map &square,  1..5;
say join ', ', @squared;        # OUTPUT: «1, 4, 9, 16, 25␤»

Infix Form

To call a subroutine with 2 arguments like an infix operator, use a subroutine reference surrounded by [ and ].

sub plus { $^a + $^b };
say 21 [&plus] 21;
# OUTPUT: «42␤»


All code objects in Perl 6 are closures, which means they can reference lexical variables from an outer scope.

sub generate-sub($x) {
    my $y = 2 * $x;
    return sub { say $y };
    #      ^^^^^^^^^^^^^^  inner sub, uses $y
my $generated = generate-sub(21);
$generated(); # OUTPUT: «42␤»

Here, $y is a lexical variable inside generate-sub, and the inner subroutine that is returned uses it. By the time that the inner sub is called, generate-sub has already exited. Yet the inner sub can still use $y, because it closed over the variable.

Another closure example is the use of map to multiply a list of numbers:

my $multiply-by = 5;
say join ', ', map { $_ * $multiply-by }, 1..5;     # OUTPUT: «5, 10, 15, 20, 25␤»

Here, the block passed to map references the variable $multiply-by from the outer scope, making the block a closure.

Languages without closures cannot easily provide higher-order functions that are as easy to use and powerful as map.


Routines are code objects that conform to type Routine, most notably Sub, Method, Regex and Submethod.

They carry additional functionality in addition to what Block supplies: they can come as multis, you can wrap them, and exit early with return:

my $keywords = set <if for unless while>;

sub has-keyword(*@words) {
    for @words -> $word {
        return True if $word (elem) $keywords;

say has-keyword 'not', 'one', 'here';       # OUTPUT: «False␤»
say has-keyword 'but', 'here', 'for';       # OUTPUT: «True␤»

Here, return doesn't just leave the block inside which it was called, but the whole routine. In general, blocks are transparent to return, they attach to the outer routine.

Routines can be inlined and as such provide an obstacle for wrapping. Use the pragma use soft; to prevent inlining to allow wrapping at runtime.

sub testee(Int $i, Str $s){
    rand.Rat * $i ~ $s;

sub wrap-to-debug(&c){
    say "wrapping {&} with arguments {&c.signature.perl}";
    &c.wrap: sub (|args){
        note "calling {&} with {args.gist}";
        my \ret-val := callwith(|args);
        note "returned from {&} with return value {ret-val.perl}";

my $testee-handler = wrap-to-debug(&testee);
# OUTPUT: «wrapping testee with arguments :(Int $i, Str $s)»

say testee(10, "ten");
# OUTPUT: «calling testee with \(10, "ten")␤returned from testee with return value "6.151190ten"␤6.151190ten»
say testee(10, "ten");
# OUTPUT: «6.151190ten␤»
Important ones: candidates, wrap, unwrap, assuming, arity, count

Defining Operators

Operators are just subroutines with funny names. The funny names are composed of the category name (infix, prefix, postfix, circumfix, postcircumfix), followed by a colon, and a list of the operator name or names (two components in the case of circumfix and postcircumfix).

This works both for adding multi candidates to existing operators and for defining new ones. In the latter case, the definition of the new subroutine automatically installs the new operator into the grammar, but only in the current lexical scope. Importing an operator via use or import also makes it available.

# adding a multi candidate to an existing operator: 
 multi infix:<+>(Int $x, "same") { 2 * $x }; 
 say 21 + "same";            # OUTPUT: «42␤» 
 # defining a new operator 
 sub postfix:<!>(Int $x where { $x >= 0 }) { [*] 1..$x }; 
 say 6!;                     # OUTPUT: «720␤» 

The operator declaration becomes available as soon as possible, so you can recurse into a just-defined operator:

sub postfix:<!>(Int $x where { $x >= 0 }) { 
     $x == 0 ?? 1 !! $x * ($x - 1)! 
 say 6!;                     # OUTPUT: «720␤» 

Circumfix and postcircumfix operators are made of two delimiters, one opening and one closing.

sub circumfix:<START END>(*@elems) { 
     "start", @elems, "end" 
 say START 'a', 'b', 'c' END;        # OUTPUT: «(start [a b c] end)␤» 

Postcircumfixes also receive the term after which they are parsed as an argument:

sub postcircumfix:<!! !!>($left, $inside) { 
     "$left -> ( $inside )" 
 say 42!! 1 !!;      # OUTPUT: «42 -> ( 1 )␤» 

Blocks can be assigned directly to operator names. Use a variable declarator and prefix the operator name with a &-sigil.

my &infix:<ieq> = -> |l { [eq] l>>.fc };
say "abc" ieq "Abc";
# OUTPUT: «True␤»


Operator precedence in Perl 6 is specified relatively to existing operators. The traits is tighter, is equiv and is looser can be provided with an operator, the new operators precedence is related to. More than one trait can be applied.

For example, infix:<*> has a tighter precedence than infix:<+>, and squeezing one in between works like this:

sub infix:<!!>($a, $b) is tighter(&infix:<+>) { 
     2 * ($a + $b) 
 say 1 + 2 * 3 !! 4;     # OUTPUT: «21␤» 

Here, the 1 + 2 * 3 !! 4 is parsed as 1 + ((2 * 3) !! 4), because the precedence of the new !! operator is between that of + and *.

The same effect could have been achieved with:

sub infix:<!!>($a, $b) is looser(&infix:<*>) { ... }

To put a new operator on the same precedence level as an existing operator, use is equiv(&other-operator) instead.


When the same operator appears several times in a row, there are multiple possible interpretations. For example:

1 + 2 + 3

could be parsed as

(1 + 2) + 3         # left associative

or as

1 + (2 + 3)         # right associative

For addition of real numbers, the distinction is somewhat moot, because + is mathematically associative.

But for other operators it matters a great deal. For example, for the exponentiation/power operator, infix:<**> :

say 2 ** (2 ** 3);      # OUTPUT: «256␤»
say (2 ** 2) ** 3;      # OUTPUT: «64␤»

Perl 6 has the following possible associativity configurations:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

You can specify the associativity of an operator with the is assoc trait, where left is the default associativity.

sub infix:<§>(*@a) is assoc<list> { 
     '(' ~ @a.join('|') ~ ')'; 
 say 1 § 2 § 3;      # OUTPUT: «(1|2|3)␤» 


Traits are subroutines that run at compile time and modify the behavior of a type, variable, routine, attribute, or other language object.

Examples of traits are:

class ChildClass is ParentClass { ... } 
 #                ^^ trait, with argument ParentClass 
 has $.attrib is rw; 
 #            ^^^^^  trait with name 'rw' 
 class SomeClass does AnotherRole { ... } 
 #               ^^^^ trait 
 has $!another-attribute handles <close>; 
 #                       ^^^^^^^ trait 

... and also is tighter, is looser, is equiv and is assoc from the previous section.

Traits are subs of the form trait_mod<VERB> , where VERB stands for the name like is, does or handles. It receives the modified thing as argument, and the name as a named argument. See Sub for details.

multi sub trait_mod:<is>(Routine $r, :$doubles!) { 
         2 * callsame; 
 sub square($x) is doubles { 
     $x * $x; 
 say square 3;       # OUTPUT: «18␤» 

See type Routine for the documentation of built-in routine traits.


There are cases in which a routine might want to call the next method from a chain. This chain could be a list of parent classes in a class hierarchy, or it could be less specific multi candidates from a multi dispatch, or it could be the inner routine from a wrap.

Fortunately, we have a series of re-dispatching tools that help us to make it easy.

sub callsame

callsame calls the next matching candidate with the same arguments that were used for the current candidate and returns that candidate's return value.

proto a(|) {*} 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callsame; 
     say "Back in Int with $res"; 
 a 1;        # OUTPUT: «Int 1␤Any 1␤Back in Int with 5␤» 

sub callwith

callwith calls the next matching candidate with arguments provided by users and returns that candidate's return value.

proto a(|) {*} 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callwith($x + 1); 
     say "Back in Int with $res"; 
 a 1;        # OUTPUT: «Int 1␤Any 2␤Back in Int with 5␤» 

Here, a 1 calls the most specific Int candidate first, and callwith re-dispatches to the less specific Any candidate. Note that although our parameter $x + 1 is an Int, still we call the next candidate in the chain.

sub nextsame

nextsame calls the next matching candidate with the same arguments that were used for the current candidate and never returns.

proto a(|) {*} 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 multi a(Int $x) { 
     say "Int $x"; 
     say "never executed because nextsame doesn't return"; 
 a 1;        # OUTPUT: «Int 1␤Any 1␤» 

sub nextwith

nextwith calls the next matching candidate with arguments provided by users and never returns.

proto a(|) {*} 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 multi a(Int $x) { 
     say "Int $x"; 
     nextwith($x + 1); 
     say "never executed because nextsame doesn't return"; 
 a 1;        # OUTPUT: «Int 1␤Any 2␤» 

sub samewith

samewith calls current candidate again with arguments provided by users and returns return value of the new instance of current candidate.

proto a(|) {*} 
 multi a(Int $x) { 
   return 1 unless $x > 1; 
   return $x * samewith($x-1); 
 say (a 10); # OUTPUT: «36288002␤» 

sub nextcallee

Redispatch may be required to call a block that is not the current scope what provides nextsame and friends with the problem to referring to the wrong scope. Use nextcallee to capture the right candidate and call it at the desired time.

proto pick-winner(|) {*} 
 multi pick-winner (Int \s) { 
     my &nextone = nextcallee;π²).then: { nextone s } 
 multi pick-winner { say "Woot! $^w won" } 
 with pick-winner ^5 .pick -> \result { 
     say "And the winner is..."; 
     await result; 
 # And the winner is... 
 # Woot! 3 won 

The Int candidate takes the nextcallee and then fires up a Promise to be executed in parallel, after some timeout, and then returns. We can't use nextsame here, because it'd be trying to nextsame the Promise's block instead of our original routine.

wrapped routines

Besides those are mentioned above, re-dispatch is helpful in more situations. One is for dispatching to wrapped routines:

# enable wrapping: 
 use soft; 
 # function to be wrapped: 
 sub square-root($x) { $x.sqrt } 
 &square-root.wrap(sub ($num) { 
    nextsame if $num >= 0; 
    1i * callwith(abs($num)); 
 say square-root(4);     # OUTPUT: «2␤» 
 say square-root(-4);    # OUTPUT: «0+2i␤» 

routines of parent class

Another use case is to re-dispatch to methods from parent classes.

class LoggedVersion is Version { 
     method new(|c) { 
         note "New version object created with arguments " ~ c.perl; 

Coercion Types

Coercion types force a specific type for routine arguments while allowing the routine itself to accept a wider input. When invoked, the arguments are narrowed automatically to the stricter type, and therefore within the routine the arguments have always the desired type.

In the case the arguments cannot be converted to the stricter type, a Type Check error is thrown.

sub double(Int(Cool) $x) { 
     2 * $x 
 say double '21';    # OUTPUT: «42␤» 
 say double  21;     # OUTPUT: «42␤» 
 say double Any;     # Type check failed in binding $x; expected 'Cool' but got 'Any' 

In the above example, the Int is the target type to which the argument $x will be coerced, and Cool is the type that the routine accepts as wider input.

If the accepted wider input type is Any, it is possible to abbreviate the coercion Int(Any) omitting the Any type, thus resulting in Int().

The coercion works by looking for a method with the same name as the target type: if such method is found on the argument, it is invoked to convert the latter to the expected narrow type. From the above, it is clear that it is possible to provide coercion among user types just providing the required methods:

class Bar { 
    has $.msg; 
 class Foo { 
    has $.msg = "I'm a foo!"; 
    # allows coercion from Foo to Bar 
    method Bar {$.msg ~ ' But I am now Bar.')); 
 # wants a Bar, but accepts Any 
 sub print-bar(Bar() $bar) { 
    say $bar.^name; # OUTPUT: «Bar␤» 
    say $bar.msg;   # OUTPUT: «I'm a foo! But I am now Bar.␤» 

In the above code, once a Foo instance is passed as argument to print-bar, the Foo.Bar method is called and the result is placed into $bar.

Coercion types are supposed to work wherever types work, but Rakudo currently (2017.05) only implements them in signatures, for both parameters and return types.

is the above referencing rakudo 2017.05 still valid? is it worth placing an example about return types?

sub MAIN

The sub with the special name MAIN is executed after all relevant phasers. Its signature is the means by which command line arguments can be parsed. Multi methods are supported and a usage method is automatically generated and displayed if no command line arguments are provided. All command line arguments are also available in @*ARGS, which can be mutated before being processed by MAIN.

Unlike other ordinary functions, any return value provided by MAIN will be ignored by the invoker, even if explicitly set by means of a return statement (that will terminate the MAIN function). The default return code of MAIN is always zero (0, success). In order to provide any return value different from zero, a call to exit has to be performed.

#|(optional description for USAGE message)
sub MAIN( Int :$length = 24,
           :file($data) where { .IO.f // die "file not found in $*CWD" } = 'file.dat',
           Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) )
    say $length if $length.defined;
    say $data   if $data.defined;
    say 'Verbosity ', ($verbose ?? 'on' !! 'off');

    exit 1;

With touch.dat present, this will work this way

$ perl6 Main.p6 
 Verbosity off 

Or this way with -v or --verbose

$ perl6 Main.p6 -v 
 Verbosity on 

The :v(:$verbose) is an alias, as explained in Signatures. In fact, since this is an alias, both verbose and v can use single or double dashes (- or --).


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

  :named-anywhere,    # allow named variables at any location
  :!foo,              # don't allow foo
sub MAIN ($a, $b, :$c, :$d) {
    say "Accepted!"

Available options are:


By default, named arguments to the program cannot be given after any positional arguments are specified. However, if %*SUB-MAIN-OPTS<named-anywhere> is set to a truthy value, named arguments can be specified anywhere, even after positional parameter. For example, the above program can be called with:

perl6 example.p6 1 --c=2 3 --d=4 

Unit-scoped definition of MAIN

If the entire script body resides within MAIN, you can use the unit declarator as follows:

unit sub MAIN( Int :$length = 24, 
                 :file($data) where { .IO.f // die "file not found in $*CWD" } = 'file.dat', 
                 Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) ); 
 # rest of script is part of MAIN 

Note that this is only appropriate if you do not need a proto or multi definition.


If no multi candidate of MAIN is found for the given command line parameters, the sub USAGE is called. If no such method is found, the compiler will output a default generated usage message.

#|(is it the answer)
multi MAIN(Int $i){ say $i == 42 ?? 'answer' !! 'dunno' }
#|(divide two numbers)
multi MAIN($a, $b){ say $a/$b }

sub USAGE(){
print Q:c:to/EOH/;
Usage: {$*PROGRAM-NAME} [number]

Prints the answer or 'dunno'.

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

18 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


Generically, an adverb is a named argument to a function. There are also some specific syntax forms that allow adverbs to be tucked into some convenient places:

q:w"foo bar";   # ":w" is a Quotelike form modifier adverb
m:g/a|b|c/;     # ":g" is also
TODO: Add this back in when :rotate on infix operators is supported 4 +> 5 :rotate # ":rotate" is an operator adverb @h{3}:exists; # ":exists" is also, but is known as a subscript adverb

Adverbs are usually expressed with colon pair notation, and for this reason colon pair notation is also known as the adverbial pair form:

:a(4)          # Same as "a" => 4

Some other forms that use a colon in ways that have adverb-like semantics are called adverbial forms. One special form starts with an integer value, followed by a name (for the key):

:20seconds     # same as seconds => 20

Also see #Colon Pair and Colon List.

Adverbial Pair

A generalized form of pair notation. They all start with the colon, like:

adverbial pair pair notation
:foo<bar> foo => 'bar'
:foo(42) foo => 42
:42foo foo => 42
:$foo foo => $foo
:foo foo => True
:!foo foo => False

Also see #Adverb and #Colon Pair and Colon List.


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


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 $;        # 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 implementation.

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 an 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"a", 4)
:a<4>          # Same as "a" => "4", same as"a", val("4"))

This is also known as the adverbial pair form. Note: when the part after the colon and before the brackets is not a legal identifier, other semantics apply, not all of which produce Pair objects.

Two other common forms are:

:a             # Same as :a(True)
:!a            # Same as :a(False)

A colon list just means that a list that contains only colon pairs, does not need commas, or even spaces:

:a(4):c:!d:c   # Same as a => 4, c => True, d => False, c => True

Finally, if there is a variable with the same name as an intended adverbial pair, you don't have to specify the name twice, but just specify the adverb with the appropriate sigil:

:$foo          # same as foo => $foo 
 :@bar          # same as bar => @bar 
 :%mapper       # same as mapper => %mapper 
 :&test         # same as test => &test 

See also #Adverb.


See 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


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 file handles, 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. put is a bit of a vague name, but because it's commonly used, it's easy to learn what it does. atomic-inc-fetch, on the other hand is rarer, and the more descriptive name helps recall its purpose better.


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 =;
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 Currently available bots are:


The #Bot on the #perl6 #IRC channel that evaluates code, e.g.:

[16:28:27]  <lizmat>  m: say "Hello world" 
 [16:28:28]  <+camelia>    rakudo-moar 812a48: OUTPUT«Hello world␤» 

This is a handy tool for showing people if the output is (un)expected.


The #Bot on the #perl6 #IRC channel that reports changes made to various Perl 6 related repositories.

[15:46:40] <+dalek> doc: 2819f25 | lizmat++ | doc/Language/glossary.pod: 
 [15:46:40] <+dalek> doc: Add stubs for stuff inside the glossary already 
 [15:46:40] <+dalek> doc: review: 


The #Bot on the #perl6 #IRC channel that provides various services to people logged in. Commands to yoleaux (a pun on YOLO) start with a period. Some often used commands are:


Leave a message to another user who is currently not logged in. The message will be relayed as soon as the user says anything on the channel.

.tell lizmat I've read the glossary 


Look up unicode codepoint information from either a codepoint, or the name of a codepoint.

[16:35:44]  <lizmat>   .u empty set 
 [16:35:45]  <yoleaux>  U+2205 EMPTY SET [Sm] (∅) 
 [16:36:29]  <lizmat>   .u ∅ 
 [16:36:30]  <yoleaux>  U+2205 EMPTY SET [Sm] (∅) 

Some #IRC clients then easily allow you to copy/paste the codepoint in question, which can be sometimes be easier than other unicode codepoint input methods.

IRC Lingo

The following terms are often used on the Perl 6 related #IRC channels:


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


Do What I Mean. A programming language designer motto.


Sometimes a test will fail under some conditions, but not others; when this test passes some test runs and fails others, it's called flapping.


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


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 ( The place where all the bugs related to #Rakudo live.


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


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


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 pre-compiled file).


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 S26 for details.

Pull Request

A feature of that allows you to make patches to be easily applied using the Github user interface. It means you request someone to do a git pull from your repository to hers. In GitHub, it can be done automatically through the web interface. 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').


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:

# A list containing infinite number of un-reified Fibonacci numbers:
my @fibonacci = 1, 1, * + * … ∞;

# We reify 10 of them, looking up the first 10 of them with array index:
say @fibonacci[^10]; # OUTPUT: «(1 1 2 3 5 8 13 21 34 55)␤»

# We reify 5 more: 10 we already reified on previous line, and we need to
# reify 5 more to get the 15th element at index 14. Even though we need only
# the 15th element, the original Seq still has to reify all previous elements:
say @fibonacci[14]; # OUTPUT: «987␤»

Above we were reifying a Seq we created with the sequence operator, but other things use the concept as well. For example, an un-reified Range is just the two end points. In some languages, calculating the sum of a huge range is a lengthy and memory-consuming process, but Perl 6 calculates it instantly:

say sum 1 .. 9_999_999_999_999; # OUTPUT: «49999999999995000000000000␤»

Why? Because the sum can be calculated without reifying the Range; that is, without figuring out all the elements it contains. This is why this feature exists. You can even make your own things reify-on-demand, using gather and take:

my $seq = gather {
    say "About to make 1st element"; take 1;
    say "About to make 2nd element"; take 2;
say "Let's reify an element!";
say $seq[0];
say "Let's reify more!";
say $seq[1];
say "Both are reified now!";
say $seq[^2];

# Let's reify an element!
# About to make 1st element
# 1
# Let's reify more!
# About to make 2nd element
# 2
# Both are reified now!
# (1 2)

Following the output above, you can see the print statements inside the gather got executed only when we reified the individual elements while looking up an element. Also note that the elements got reified just once. When we printed the same elements again on the last line of the example, the messages inside gather was no longer printed. This is because the construct used already-reified elements from the Seq's cache.

Note that above we assigned the gather to a Scalar container (the $ sigil), not the Positional one (the @ sigil). The reason is that the @-sigiled variables are mostly eager. What this means is they reify the stuff assigned to them right away most of the time. The only time they don't do it is when the items are known to be is-lazy, like our sequence generated with infinity as the end point. Were we to assign the gather to a @-variable, the say statements inside of it would've been printed right away.

Another way to fully-reify a list, is by calling .elems on it. This is the reason why checking whether a list contains any items is best done by using .Bool method (or just using if @array { … }), since you don't need to reify all the elements to find out if there are any of them.

There are times where you do want to fully-reify a list before doing something. For example, the IO::Handle.lines returns a Seq. The following code contains a bug; keeping reification in mind, try to spot it:

my $fh = "/tmp/bar"; 
 my $lines = $fh.lines; 
 close $fh; 
 say $lines[0]; 

We open a file handle, then assign return of .lines to a Scalar variable, so the returned Seq does not get reified right away. We then close the file handle, and try to print an element from $lines.

The bug in the code is by the time we reify the $lines Seq on the last line, we've already closed the file handle. When the Seq's iterator tries to generate the item we've requested, it results in the error about attempting to read from a closed handle. So, to fix the bug we can either assign to a @-sigiled variable or call .elems on $lines before closing the handle:

my $fh = "/tmp/bar"; 
 my @lines = $fh.lines; 
 close $fh; 
 say @lines[0]; # no problem! 

Also good:

my $fh = "/tmp/bar"; 
 my $lines = $fh.lines; 
 say "Read $lines.elems() lines"; #reifying before closing handle 
 close $fh; 
 say $lines[0]; # no problem! 


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.


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: 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 Perl6's object system, and are declared using the keyword role 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.


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 run-time 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 is the "standard" Perl 6 grammar definition, see that was used to implement Perl 6. 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:

["", => "C", meta => [], config => {}, contents => ["foo"]),""] 

Note the twine is an array with an odd number of elements beginning with a simple string, alternating with formatting code objects and simple strings, and ending with a simple string. (The formatting code objects are intertwined with the strings.) The strings may be empty (as shown in the example). A twine with no formatting code will contain one simple string.

Type objects

A type object is an object that is used to represent a type or a class. Since in object oriented programming everything is an object, classes are objects too, which inherit from the ur-class which, in our case, is Mu.


A value is what is actually contained in a container such as a variable. Used in expressions such as lvalue, to indicate that that particular container can be assigned to.

Value type

A type is known as a value type if it is immutable and any instance of that type is interchangeable with any other instance "of the same value"—that is, any instance constructed in the same way. An instance of a value type is often called a value (but should not be confused with #lvalues or #rvalues).

For example, numbers are value types, so a number constructed one place in your program with, for instance, the literal 3 can't be changed in any way—it simply is 3—and any later use of the literal 3 can safely be pointed at the same place in memory as the first with no ill consequences.

Classes doing the roles Numeric and Stringy are among a few examples of built-in value types.

A value type is created by ensuring that an instance of the value type is immutable (i.e., its attributes cannot be modified after construction) and that its WHICH method returns the same thing every time an instance with the same value is constructed (and conversely returns a different thing every time an instance with a different value is constructed).

The language is free to optimize based on the assumption that equivalent instances of value types are interchangeable, but you should not depend on any such optimization. For instance, if you want clone to return an instance of self, or you want instance construction to be memoized so that re-construction of a previously-constructed value always returns the same instance, you currently must override this behavior yourself.

(The same would hold true of object finalization, but if your instances need special destruction behavior, you almost certainly do not actually have a value type. Values should be thought of as "timeless" and existing in some ideal form outside of your program's memory, like natural values are.)


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


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.

19 Grammar Tutorial

An introduction to grammars

Before We Start

Why grammars?

Grammars parse strings and return data structures from those strings. Grammars can be used to prepare a program for execution, to determine if a program can run at all (if it's a valid program), to break down a web page into constituent parts, or to identify the different parts of a sentence, among other things.

When would I use grammars?

If you have strings to tame or interpret, grammars provide the tools to do the job.

The string could be a file that you're looking to break into sections; perhaps a protocol, like SMTP, where you need to specify which "commands" come after what user-supplied data; maybe you're designing your own domain specific language. Grammars can help.

The broad concept of grammars

Regular expressions (Regexes) work well for finding patterns in strings. However, for some tasks, like finding multiple patterns at once, or combining patterns, or testing for patterns that may surround strings regular expressions, alone, are not enough.

When working with HTML, you could define a grammar to recognize HTML tags, both the opening and closing elements, and the text in between. You could then organize these elements into data structures, such as arrays or hashes.

Getting More Technical

The conceptual overview

Grammars are a special kind of class. You declare and define a grammar exactly as you would any other class, except that you use the grammar keyword instead of class.

grammar G { ... } 

Grammars are made up of methods that define a regex, a token, or a rule. These are all varieties of different types of match methods. Once you have a grammar defined, you call it and pass in a string for parsing.

my $matchObject = G.parse($string); 

Now, you may be wondering, if I have all these regexes defined that just return their results, how does that help with parsing strings that may be ahead or backwards in a string, or things that need to be combined from many of those regexes... And that's where grammar actions come in.

For every "method" you match in your grammar, you get an action you can use to act on that match. You also get an overarching action that you can use to tie together all your matches and to build a data structure. This overarching method is called TOP by default.

The technical overview

As already mentioned, grammars are declared using the grammar keyword and its "methods" are declared with regex, or token, or rule.

When a method (regex, token or rule) matches in the grammar, the string matched is put into a match object and keyed with the same name as the method.

grammar G { 
     token TOP { <thingy> .* } 
     token thingy { 'clever_text_keyword' } 

If you were to use my $match = G.parse($string) and your string started with 'clever_text_keyword', you would get a match object back that contained 'clever_text_keyword' keyed by the name of <thingy> in your match object.

The TOP method (whether regex, token, or rule) is the overarching pattern that must match everything (by default). If the parsed string doesn't match the TOP regex, your returned match object will be empty (Nil).

As you can see above, in TOP, the <thingy> token is mentioned. The <thingy> is defined on the next line. That means that 'clever_text_keyword' must be the first thing in the string, or the grammar parse will fail and we'll get an empty match. This is great for recognizing a malformed string that should be discarded.

Learning By Example - a REST Contrivance

Let's suppose we'd like to parse a URI into the component parts that make up a RESTful request. We want the URIs to work like this:

So, if we have "/product/update/7/notify", we would want our grammar to give us a match object that has a subject of "product", a command of "update", and data of "7/notify".

We'll start by defining a grammar class and some match methods for the subject, command, and data. We'll use the token declarator since we don't care about whitespace.

grammar REST { 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 

So far, this REST grammar says we want a subject that will be just word characters, a command that will be just word characters, and data that will be everything else left in the string.

Next, we'll want to arrange these matching tokens within the larger context of the URI. That's what the TOP method allows us to do. We'll add the TOP method and place the names of our tokens within it, together with the rest of the patterns that makes up the overall pattern. Note how we're building a larger regex from our named regexes.

grammar REST { 
     token TOP     { '/' <subject> '/' <command> '/' <data> } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 

With this code, we can already get the three parts of our RESTful request:

my $match = REST.parse('/product/update/7/notify'); 
 say $match; 
 # OUTPUT: «「/product/update/7/notify」␤ 
 #          subject => 「product」 
 #          command => 「update」 
 #          data => 「7/notify」» 

The data can be accessed directly by using $match<subject> or $match<command> or $match<data> to return the values parsed. They each contain match objects that you can work further with, such as coercing into a string ( $match<command>.Str ).

Adding some flexibility

So far, the grammar will handle retrieves, deletes and updates. However, a create command doesn't have the third part (the data portion). This means the grammar will fail to match if we try to parse a create URI. To avoid this, we need to make that last data position match optional, along with the '/' preceding it. This is accomplished by adding a question mark to the grouped '/' and data components of the TOP token, to indicate their optional nature, just like a normal regex.

So, now we have:

grammar REST { 
     token TOP     { '/' <subject> '/' <command> [ '/' <data> ]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 my $m = REST.parse('/product/create'); 
 say $m<subject>, $m<command>; 
 # OUTPUT: «「product」「create」␤» 

Next, assume that the URIs will be entered manually by a user and that the user might accidentally put spaces between the '/'s. If we wanted to accommodate for this, we could replace the '/'s in TOP with a token that allowed for spaces.

grammar REST { 
     token TOP     { <slash><subject><slash><command>[<slash><data>]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 my $m = REST.parse('/ product / update /7 /notify'); 
 say $m; 
 # OUTPUT: «「/ product / update /7 /notify」␤ 
 #          slash => 「/ 」 
 #          subject => 「product」 
 #          slash => 「 / 」 
 #          command => 「update」 
 #          slash => 「 /」 
 #          data => 「7 /notify」» 

We're getting some extra junk in the match object now, with those slashes. There's techniques to clean that up that we'll get to later.

Inheriting from a grammar

Since grammars are classes, they behave, OOP-wise, in the same way as any other class; specifically, they can inherit from base classes that include some tokens or rules, this way:

grammar Letters { 
     token letters { \w+ } 
 grammar Quote-Quotes { 
     token quote { "\""|"`"|"'" } 
 grammar Quote-Other { 
     token quote { "|"|"/"|"¡" } 
 grammar Quoted-Quotes is Letters is Quote-Quotes { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 grammar Quoted-Other is Letters is Quote-Other { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 my $quoted = q{"enhanced"}; 
 my $parsed = Quoted-Quotes.parse($quoted); 
 say $parsed; 
 # 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.

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 =>; 
 #   …or if you prefer… 
 my $matchObject = REST.parse($uri, :actions(; 

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

20 Grammars

Parsing and interpreting text

Grammar is a powerful tool used to destructure text and often to return data structures that have been created by interpreting that text.

For example, Perl 6 is parsed and executed using a Perl 6-style grammar.

An example that's more practical to the common Perl 6 user is the JSON::Tiny module, which can deserialize any valid JSON file, however the deserializing code is written in less than 100 lines of simple, extensible code.

If you didn't like grammar in school, don't let that scare you off grammars. Grammars allow you to group regexes, just as classes allow you to group methods of regular code.

Named Regexes

The main ingredient of grammars is named regexes. While the syntax of Perl 6 Regexes is outside the scope of this document, named regexes have a special syntax, similar to subroutine definitions:

In fact, named regexes can even take extra arguments, using the same syntax as subroutine parameter lists

my regex number { \d+ [ \. \d+ ]? } 

In this case, we have to specify that the regex is lexically scoped using the my keyword, because named regexes are normally used within grammars.

Being named gives us the advantage of being able to easily reuse the regex elsewhere:

say so "32.51" ~~ &number;                         # OUTPUT: «True␤» 
 say so "15 + 4.5" ~~ /<number>\s* '+' \s*<number>/ # OUTPUT: «True␤» 

regex isn't the only declarator for named regexes. In fact, it's the least common. Most of the time, the token or rule declarators are used. These are both ratcheting, which means that the match engine won't back up and try again if it fails to match something. This will usually do what you want, but isn't appropriate for all cases:

my regex works-but-slow { .+ q } 
 my token fails-but-fast { .+ q } 
 my $s = 'Tokens won\'t backtrack, which makes them fail quicker!'; 
 say so $s ~~ &works-but-slow; # OUTPUT: «True␤» 
 say so $s ~~ &fails-but-fast; # OUTPUT: «False␤» 
                               # the entire string get taken by the .+ 

Note that non-backtracking works on terms, that is, as the example below, if you have matched something, then you will never backtrack. But when you fail to match, if there is another candidate introduced by | or ||, you will retry to match again.

my token tok-a { .* d  }; 
 my token tok-b { .* d | bd }; 
 say so "bd" ~~ &tok-a;        # OUTPUT: «False␤» 
 say so "bd" ~~ &tok-b;        # OUTPUT: «True␤» 


The only difference between the token and rule declarators is that the rule declarator causes :sigspace to go into effect for the Regex:

my token non-space-y { 'once' 'upon' 'a' 'time' } 
 my rule space-y { 'once' 'upon' 'a' 'time' } 
 say so 'onceuponatime'    ~~ &non-space-y; # OUTPUT: «True␤» 
 say so 'once upon a time' ~~ &non-space-y; # OUTPUT: «False␤» 
 say so 'onceuponatime'    ~~ &space-y;     # OUTPUT: «False␤» 
 say so 'once upon a time' ~~ &space-y;     # OUTPUT: «True␤» 

Creating Grammars

Group of named regexes that form a formal grammar

Grammar is the superclass that classes automatically get when they are declared with the grammar keyword instead of class. Grammars should only be used to parse text; if you wish to extract complex data, you can add actions within the grammar, or an action object is recommended to be used in conjunction with the grammar.

Proto regexes

Grammars are composed of rules, tokens and regexes; they are actually methods, since grammars are classes. These methods can share a name and functionality in common, and thus can use proto.

For instance, if you have a lot of alternations, it may become difficult to produce readable code or subclass your grammar. In the Actions class below, the ternary in method TOP is less than ideal and it becomes even worse the more operations we add:

grammar Calculator {
    token TOP { [ <add> | <sub> ] }
    rule  add { <num> '+' <num> }
    rule  sub { <num> '-' <num> }
    token num { \d+ }

class Calculations {
    method TOP ($/) { make $<add> ?? $<add>.made !! $<sub>.made; }
    method add ($/) { make [+] $<num>; }
    method sub ($/) { make [-] $<num>; }

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

To make things better, we can use proto regexes that look like :sym<...> adverbs on tokens:

grammar Calculator {
    token TOP { <calc-op> }

    proto rule calc-op          {*}
          rule calc-op:sym<add> { <num> '+' <num> }
          rule calc-op:sym<sub> { <num> '-' <num> }

    token num { \d+ }

class Calculations {
    method TOP              ($/) { make $<calc-op>.made; }
    method calc-op:sym<add> ($/) { make [+] $<num>; }
    method calc-op:sym<sub> ($/) { make [-] $<num>; }

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

In the grammar, the alternation has now been replaced with <calc-op>, which is essentially the name of a group of values we'll create. We do so by defining a rule prototype with proto rule calc-op. Each of our previous alternations have been replaced by a new rule calc-op definition and the name of the alternation is attached with :sym<> adverb.

In the actions class, we now got rid of the ternary operator and simply take the .made value from the $<calc-op> match object. And the actions for individual alternations now follow the same naming pattern as in the grammar: method calc-op:sym<add> and method calc-op:sym<sub>.

The real beauty of this method can be seen when you subclass that grammar and actions class. Let's say we want to add a multiplication feature to the calculator:

grammar BetterCalculator is Calculator { 
     rule calc-op:sym<mult> { <num> '*' <num> } 
 class BetterCalculations is Calculations { 
     method calc-op:sym<mult> ($/) { make [*] $<num> } 
 say BetterCalculator.parse('2 * 3', actions => BetterCalculations).made; 
 # OUTPUT: «6␤» 

All we had to add are additional rule and action to the calc-op group and the thing works—all thanks to proto regexes.

Special Tokens


grammar Foo {
    token TOP { \d+ }

The TOP token is the default first token attempted to match when parsing with a grammar. Note that if you're parsing with .parse method, token TOP is automatically anchored to the start and end of the string. If you don't want to parse the whole string, look up .subparse.

Using rule TOP or regex TOP are also acceptable.

A different token can be chosen to be matched first using the :rule named argument to .parse, .subparse, or .parsefile. These are all Grammar methods.


When rule instead of token is used, any whitespace after an atom is turned into a non-capturing call to ws, written as <.ws> where . means non-capturing. That is to say:

rule entry { <key> '=' <value> }

Is the same as:

token entry { <key> <.ws> '=' <.ws> <value> <.ws> }

The default ws matches one or more whitespace characters (\s) or a word boundary (<|w>):

# First <.ws> matches word boundary at the start of the line
# and second <.ws> matches the whitespace between 'b' and 'c'
say 'ab   c' ~~ /<.ws> ab <.ws> c /; # OUTPUT: «「ab   c」␤»

# Failed match: there is neither any whitespace nor a word
# boundary between 'a' and 'b'
say 'ab' ~~ /. <.ws> b/;             # OUTPUT: «Nil␤»

# Successful match: there is a word boundary between ')' and 'b'
say ')b' ~~ /. <.ws> b/;             # OUTPUT: «「)b」␤»

You can also redefine the default ws token:

grammar Foo {
    rule TOP { \d \d }
}.parse: "4   \n\n 5"; # Succeeds

grammar Bar {
    rule TOP { \d \d }
    token ws { \h*   }
}.parse: "4   \n\n 5"; # Fails


The <sym> token can be used inside proto regexes to match the string value of the :sym adverb for that particular regex:

grammar Foo {
    token TOP { <letter>+ }
    proto token letter {*}
    token letter:sym<P> { <sym> }
    token letter:sym<e> { <sym> }
    token letter:sym<r> { <sym> }
    token letter:sym<l> { <sym> }
    token letter:sym<*> {   .   }
}.parse("I ♥ Perl", actions => class {
    method TOP($/) { make $<letter>.grep(*.<sym>).join }
}).made.say; # OUTPUT: «Perl␤»

This comes in handy when you're already differentiating the proto regexes with the strings you're going to match, as using <sym> token prevents repetition of those strings.

Always Succeed Assertion

The <?> is the always succeed assertion. When used as a grammar token, it can be used to trigger an Action class method. In the following grammar we look for Arabic digits and define a succ token with the always succeed assertion.

In the action class, we use calls to the succ method to do set up (in this case, we prepare a new element in @!numbers). In the digit method, we convert an Arabic digit into a Devanagari digit and add it to the last element of @!numbers. Thanks to succ, the last element will always be the number for the currently parsed digit digits.

grammar Digifier {
    rule TOP {
        [ <.succ> <digit>+ ]+
    token succ   { <?> }
    token digit { <[0..9]> }

class Devanagari {
    has @!numbers;
    method digit ($/) { @!numbers[*-1] ~= $/.ord.&[+](2358).chr }
    method succ  ($)  { @!numbers.push: ''     }
    method TOP   ($/) { make @!numbers[^(*-1)] }

say Digifier.parse('255 435 777', actions =>;
# OUTPUT: «(२५५ ४३५ ७७७)␤»

Methods in Grammar

It's fine to use methods instead of rules or tokens in a grammar, as long as they return a Cursor:

grammar DigitMatcher {
    method TOP (:$full-unicode) {
        $full-unicode ?? self.num-full !! self.num-basic;
    token num-full  { \d+ }
    token num-basic { <[0..9]>+ }

The grammar above will attempt different matches depending on the arguments provided by parse methods:

say +DigitMatcher.subparse: '12७१७९०९', args => \(:full-unicode); 
 # OUTPUT: «12717909␤» 
 say +DigitMatcher.subparse: '12७१७९०९', args => \(:!full-unicode); 
 # OUTPUT: «12␤» 

Action Objects

A successful grammar match gives you a parse tree of Match objects, and the deeper that match tree gets, and the more branches in the grammar are, the harder it becomes to navigate the match tree to get the information you are actually interested in.

To avoid the need for diving deep into a match tree, you can supply an actions object. After each successful parse of a named rule in your grammar, it tries to call a method of the same name as the grammar rule, giving it the newly created Match object as a positional argument. If no such method exists, it is skipped.

Here is a contrived example of a grammar and actions in action:

grammar TestGrammar { 
     token TOP { \d+ } 
 class TestActions { 
     method TOP($/) { 
         $/.make(2 + $/); 
 my $match = TestGrammar.parse('40', actions =>; 
 say $match;         # OUTPUT: «「40」␤» 
 say $match.made;    # OUTPUT: «42␤» 

An instance of TestActions is passed as named argument actions to the parse call, and when token TOP has matched successfully, it automatically calls method TOP, passing the match object as an argument.

To make it clear that the argument is a match object, the example uses $/ as a parameter name to the action method, though that's just a handy convention, nothing intrinsic. $match would have worked too. (Though using $/ does give the advantage of providing $<capture> as a shortcut for $/<capture>).

A slightly more involved example follows:

grammar KeyValuePairs { 
     token TOP { 
         [<pair> \n+]* 
     token ws { 
     rule pair { 
         <key=.identifier> '=' <value=.identifier> 
     token identifier { 
 class KeyValuePairsActions { 
     method pair      ($/) { 
         $/.make: $<key>.made => $<value>.made 
     method identifier($/) { 
         # subroutine `make` is the same as calling .make on $/ 
         make ~$/ 
     method TOP ($match) { 
         # can use any variable name for parameter, not just $/ 
         $match.make: $match<pair>».made 
 my $actions = KeyValuePairsActions; 
 my $res = KeyValuePairs.parse(q:to/EOI/, :$actions).made; 
 for @$res -> $p { 
     say "Key: $p.key()\tValue: $p.value()"; 

This produces the following output:

Key: second     Value: b 
 Key: hits       Value: 42 
 Key: perl       Value: 6 

Rule pair, which parsed a pair separated by an equals sign, aliases the two calls to token identifier to separate capture names to make them available more easily and intuitively. The corresponding action method constructs a Pair object, and uses the .made property of the sub match objects. So it (like the action method TOP too) exploits the fact that action methods for submatches are called before those of the calling/outer regex. So action methods are called in post-order.

The action method TOP simply collects all the objects that were .made by the multiple matches of the pair rule, and returns them in a list.

Also note that KeyValuePairsActions was passed as a type object to method parse, which was possible because none of the action methods use attributes (which would only be available in an instance).

In other cases, action methods might want to keep state in attributes. Then of course you must pass an instance to method parse.

Note that token ws is special: when :sigspace is enabled (and it is when we are using rule), it replaces certain whitespace sequences. This is why the spaces around the equals sign in rule pair work just fine and why the whitespace before closing } does not gobble up the newlines looked for in token TOP.

21 Perl 6 from Haskell - 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) { => $p.x, y => $p.y + 1) 

The code I illustrated above is an example of a Product Type. If instead you'd like to write a Sum Type, there is not an exact equivalent in Perl 6. The closest thing would be an Enum.

data Animal = Dog | Cat | Bird | Horse 
 testAnimal :: Animal -> String 
 testAnimal Dog   = "Woof" 
 testAnimal Horse = "Neigh" 

A Perl 6 Enum does not fit the same exact use cases, but it can be used in putting constraints on types.

enum Animal < Dog Cat Bird Horse >; 
 proto sub test-animal( Animal        ) {*} 
 multi sub test-animal( Dog           ) { 'Woof' } 
 multi sub test-animal( Animal::Horse ) { 'Neigh'  }   # more explicit 
 say test-animal Animal::Dog; # more explicit 
 say test-animal Horse; 

Type Aliases and Subsets

In Haskell, you can alias an existing type to simply increase clarity of intent and re-use existing types.

type Name = String 
 fullName :: Name -> Name -> Name 
 fullName first last = first ++ last 

The equivalent in Perl 6 is the following.

my constant Name = Str; 
 sub full-name ( Name \first, Name \last --> Name ) { first ~ last } 

It should be noted that in Perl 6, one can also create a subset of an existing type.

subset Name of Str where *.chars < 20; 
 sub full-name(Name $first, Name $last) { 
   $first ~ $last 
 full-name("12345678901234567890111", "Smith") # This does not compile, as the first parameter 
                                               # doesn't fit the Name type 



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 smart match 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:

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 meta operator 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);       # True 
 (1 .. 100); # 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


22 Input/Output The Definitive Guide

Correctly use Perl 6 IO

The Basics

The vast majority of common IO work is done by the IO::Path type. If you want to read from or write to a file in some form or shape, this is the class you want. It abstracts away the details of file handles (or "file descriptors") and so you mostly don't even have to think about them.

Behind the scenes, IO::Path works with IO::Handle; a class which you can use directly if you need a bit more control than what IO::Path provides. When working with other processes, e.g. via Proc or Proc::Async types, you'll also be dealing with a subclass of IO::Handle: the IO::Pipe.

Lastly, you have the IO::CatHandle, as well as IO::Spec and its subclasses, that you'll rarely, if ever, use directly. These classes give you advanced features, such as operating on multiple files as one handle, or low-level path manipulations.

Along with all these classes, Perl 6 provides several subroutines that let you indirectly work with these classes. These come in handy if you like functional programming style or in Perl 6 one liners.

While IO::Socket and its subclasses also have to do with Input and Output, this guide does not cover them.

Navigating Paths

What's an IO::Path Anyway?

To represent paths as either files or directories, use IO::Path type. The simplest way to obtain an object of that type is to coerce a Str by calling .IO method on it:

say 'my-file.txt'.IO; # OUTPUT: «"my-file.txt".IO␤»

It may seem like something is missing here—there is no volume or absolute path involved—but that information is actually present in the object. You can see it by using .perl method:

say 'my-file.txt'.IO.perl;
# OUTPUT: «"my-file.txt", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))␤»

The two extra attributes—SPEC and CWD—specify what type of operating system semantics the path should use as well as the "current working directory" for the path, i.e. if it's a relative path, then it's relative to that directory.

This means that regardless of how you made one, an IO::Path object technically always refers to an absolute path. This is why its .absolute and .relative methods return Str objects and they are the correct way to stringify a path.

However, don't be in a rush to stringify anything. Pass paths around as IO::Path objects. All the routines that operate on paths can handle them, so there's no need to convert them.

Working with Files

Writing into files

Writing new content

Let's make some files and write and read data from them! The spurt and slurp routines write and read the data in one chunk. Unless you're working with very large files that are difficult to store entirely in memory all at the same time, these two routines are for you.

"my-file.txt".IO.spurt: "I ♥ Perl!"; 

The code above creates a file named my-file.txt in the current directory and then writes text I ♥ Perl! into it. If Perl 6 is your first language, celebrate your accomplishment! Try to open the file you created with some other program to verify what you wrote with your program. If you already know some other language, you may be wondering if this guide missed anything like handling encoding or error conditions.

However, that is all the code you need. The string will be encoded in utf-8 encoding by default and the errors are handled via the Failure mechanism: these are exceptions you can handle using regular conditionals. In this case, we're letting all potential Failures get sunk after the call and so any Exceptions they contain will be thrown.

Appending content

If you wanted to add more content to the file we made in previous section, you could note the spurt documentation mentions :append argument. However, for finer control, let's get ourselves an IO::Handle to work with:

my $fh = 'my-file.txt' :a; 
 $fh.print: "I count: "; 
 $fh.print: "$_ " for ^10; 

The .open method call opens our IO::Path and returns an IO::Handle. We passed :a as argument, to indicate we want to open the file for writing in append mode.

In the next two lines of code, we use the usual .print method on that IO::Handle to print a line with 11 pieces of text (the 'I count: ' string and 10 numbers). Note that, once again, Failure mechanism takes care of all the error checking for us. If the .open fails, it returns a Failure, which will throw when we attempt to call method .print on it.

Finally, we close the IO::Handle by calling the .close method on it. It is important that you do it, especially in large programs or ones that deal with a lot of files, as many systems have limits to how many files a program can have open at the same time. If you don't close your handles, eventually you'll reach that limit and the .open call will fail. Note that unlike some other languages, Perl 6 does not use reference counting, so the file handles are NOT closed when the scope they're defined in is left. They will be closed only when they're garbage collected and failing to close the handles may cause your program to reach the file limit before the open handles get a chance to get garbage collected.

Reading from files

Using IO::Path

We've seen in previous sections that writing stuff to files is a single-line of code in Perl 6. Reading from them, is similarly easy:

say 'my-file.txt'.IO.slurp;        # OUTPUT: «I ♥ Perl!␤» 
 say 'my-file.txt'.IO.slurp: :bin;  # OUTPUT: «Buf[uint8]:0x<49 20 e2 99 a5 20 50 65 72 6c 21>␤» 

The .slurp method reads entire contents of the file and returns them as a single Str object, or as a Buf object, if binary mode was requested, by specifying :bin named argument.

Since slurping loads the entire file into memory, it's not ideal for working with huge files.

The IO::Path type offers two other handy methods: .words and .lines that lazily read the file in smaller chunks and return Seq objects that (by default) don't keep already-consumed values around.

Here's an example that finds lines in a text file that mention Perl and prints them out. Despite the file itself being too large to fit into available RAM, the program will not have any issues running, as the contents are processed in small chunks:

.say for '500-PetaByte-File.txt'.IO.lines.grep: *.contains: 'Perl'; 

Here's another example that prints the first 100 words from a file, without loading it entirely:

.say for '500-PetaByte-File.txt'.IO.words: 100 

Note that we did this by passing a limit argument to .words instead of, say, using a list indexing operation. The reason for that is there's still a file handle in use under the hood, and until you fully consume the returned Seq, the handle will remain open. If nothing references the Seq, eventually the handle will get closed, during a garbage collection run, but in large programs that work with a lot of files, it's best to ensure all the handles get closed right away. So, you should always ensure the Seq from IO::Path's .words and .lines methods is fully reified; and the limit argument is there to help you with that.

Using IO::Handle

Of course, you can read from files using the IO::Handle type, which gives you a lot finer control over what you're doing:

given 'some-file.txt' { 
     say .readchars: 8;  # OUTPUT: «I ♥ Perl␤» 
     .seek: 1, SeekFromCurrent; 
     say .readchars: 15;  # OUTPUT: «I ♥ Programming␤» 

The IO::Handle gives you .read, .readchars, .get, .getc, .words, .lines, .slurp, .comb, .split, and .Supply methods to read data from it. Plenty of options; and the catch is you need to close the handle when you're done with it.

Unlike some languages, the handle won't get automatically closed when the scope it's defined in is left. Instead, it'll remain open until it's garbage collected. To make the closing business easier, some of the methods let you specify a :close argument, you can also use the will leave trait, or the does auto-close trait provided by the Trait::IO module.

The Wrong Way To Do Things

This section describes how NOT to do Perl 6 IO.

Leave $*SPEC Alone

You may have heard of $*SPEC and seen some code or books show its usage for splitting and joining path fragments. Some of the routine names it provides may even look familiar to what you've used in other languages.

However, unless you're writing your own IO framework, you almost never need to use $*SPEC directly. $*SPEC provides low-level stuff and its use will not only make your code tough to read, you'll likely introduce security issues (e.g. null characters)!

The IO::Path type is the workhorse of Perl 6 world. It caters to all the path manipulation needs as well as provides shortcut routines that let you avoid dealing with file handles. Use that instead of the $*SPEC stuff.

Tip: you can join path parts with / and feed them to IO::Path's routines; they'll still do The Right Thing™ with them, regardless of the operating system.

 my $fh = open $*SPEC.catpath: '', 'foo/bar', $file; 
 my $data = $fh.slurp; 
# RIGHT! Use IO::Path to do all the dirty work 
 my $data = 'foo/bar'.IO.add($file).slurp; 

However, it's fine to use it for things not otherwise provided by IO::Path. For example, the .devnull method:

     temp $*OUT = open :w, $*SPEC.devnull; 
     say "In space no one can hear you scream!"; 
 say "Hello"; 

Stringifying IO::Path

Don't use the .Str method to stringify IO::Path objects, unless you just want to display them somewhere for information purposes or something. The .Str method returns whatever basic path string the IO::Path was instantiated with. It doesn't consider the value of the $.CWD attribute. For example, this code is broken:

 my $path = 'foo'.IO; 
 chdir 'bar'; 
 run <tar -cvvf archive.tar>, ~$path; 

The chdir call changed the value of the current directory, but the $path we created is relative to the directory before that change.

However, the IO::Path object does know what directory it's relative to. We just need to use .absolute or .relative to stringify the object. Both routines return a Str object; they only differ in whether the result is an absolute or relative path. So, we can fix our code like this:

# RIGHT!! .absolute does consider the value of $.CWD! 
 my $path = 'foo'.IO; 
 chdir 'bar'; 
 run <tar -cvvf archive.tar>, $path.absolute; 
 # Also good: 
 run <tar -cvvf archive.tar>, $path.relative; 

Be mindful of $*CWD

While usually out of view, every IO::Path object, by default, uses the current value of $*CWD to set its $.CWD attribute. This means there are two things to pay attention to.

temp the $*CWD

This code is a mistake:

# WRONG!! 
 my $*CWD = "foo".IO; 

The my $*CWD made $*CWD undefined. The .IO coercer then goes ahead and sets the $.CWD attribute of the path it's creating to the stringified version of the undefined $*CWD; an empty string.

The correct way to perform this operation is use temp instead of my. It'll localize the effect of changes to $*CWD, just like my would, but it won't make it undefined, so the .IO coercer will still get the correct old value:

temp $*CWD = "foo".IO; 

Better yet, if you want to perform some code in a localized $*CWD, use the indir routine for that purpose.

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

Here we explicitly close the file handle 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., $* 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 file handle 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/".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


Many programs need to be able to run other programs. Running a program in Perl 6 is as easy as:

run 'git', 'status';

This line runs the program named "git" and passes "git" and "status" to its command-line. It will find the program using the %*ENV<PATH> setting.

If you would like to run a program by sending a command-line to the shell, there's a tool for that as well. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on.

shell 'ls -lR | gzip -9 > ls-lR.gz';

Caution should be taken when using shell with user input.


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


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

Here is a small program that uses the "tail" program to print out the contents of the log named system.log for 10 seconds and then tells the program to stop with a QUIT signal.

Whereas Proc provides access to output using IO::Handles, Proc::Async provides access using asynchronous supplies (see Supply).

If you want to run a program and do some work while you wait for the original program to finish, the start routine returns a Promise, which is kept when the program quits.

Use the write method to pass data into the program.

25 Lists, Sequences, and Arrays

Positional data constructs

Lists have been a central part of computing since before there were computers, during which time many devils have taken up residence in their details. They were actually one of the hardest parts of Perl 6 to design, but through persistence and patience, Perl 6 has arrived with an elegant system for handling them.

Literal Lists

Literal List s are created with commas and semicolons not with parentheses, so:

1, 2;        # This is two-element list
our $list = (1, 2);      # This is also a List, in parentheses
$list = (1; 2);      # same List (see below)
$list = (1);         # This is not a List, just a 1 in parentheses
$list = (1,);        # This is a one-element List

There is one exception, empty lists are created with just parenthesis:

();          # This is an empty List 
 (,);         # This is a syntax error 

Note that hanging commas are just fine as long as the beginning and end of a list are clear, so feel free to use them for easy code editing.

Parentheses can be used to mark the beginning and end of a List, so:

(1, 2), (1, 2); # This is a list of two lists.

Lists of Lists can also be created by combining comma and semicolon. This is also called multi-dimensional syntax, because it is most often used to index multidimensional arrays.

say so (1,2; 3,4) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so (1,2; 3,4;) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so ("foo";) eqv ("foo") eqv (("foo")); # not a list
# OUTPUT: «True␤»

Unlike a comma, a hanging semicolon does not create a multidimensional list in a literal. However, be aware that this behavior changes in most argument lists, where the exact behavior depends on the function... but will usually be:

say('foo';);   # a list with one element and the empty list
# OUTPUT: «(foo)()␤»
say(('foo';)); # no list, just the string "foo"
# OUTPUT: «foo␤»

Because the semicolon doubles as a statement terminator it will end a literal list when used at the top level, instead creating a statement list. If you want to create a statement list inside parenthesis, use a sigil before the parenthesis:

say so (42) eqv $(my $a = 42; $a;);
# OUTPUT: «True␤»
say so (42,42) eqv (my $a = 42; $a;);
# OUTPUT: «True␤»

Individual elements can be pulled out of a list using a subscript. The first element of a list is at index number zero:

say (1, 2)[0];  # says 1 
 say (1, 2)[1];  # says 2 
 say (1, 2)[2];  # says Nil 
 say (1, 2)[-1]; # Error 
 say ((<a b>,<c d>),(<e f>,<g h>))[1;0;1]; # says "f" 

The @ sigil

Variables in Perl 6 whose names bear the @ sigil are expected to contain some sort of list-like object. Of course, other variables may also contain these objects, but @-sigiled variables always do, and are expected to act the part.

By default, when you assign a List to an @-sigiled variable, you create an Array. Those are described below. If, instead you want to put an actual List into an @-sigiled variable, you can use binding with := instead.

my @a := 1, 2, 3;

One of the ways @-sigiled variables act like lists is by always supporting positional subscripting. Anything bound to a @-sigiled value must support the Positional role which guarantees this:

my @a := 1; # Type check failed in binding; expected Positional but got Int

Reset a List Container

To remove all elements from a Positional container assign Empty, the empty list () or a Slip of the empty list to the container.

my @a = 1, 2, 3;
@a = ();
@a = Empty;
@a = |();


All lists may be iterated, which means taking each element from the list in order and stopping after the last element:

for 1, 2, 3 { .say }  # OUTPUT: «1␤2␤3␤»

Single Argument Rule

It is the rule by which the set of parameters passed to an iterator such as for is treated as a single argument, instead of several arguments; that is some-iterator( a, b, c, ...) will always be treated as some-iterator( list-or-array(a, b, c)) and never as (some-iterator(a))(b)..., that is, iterative application of the iterator to the first argument, then the result to the next argument, and so on. In this example

my @list = [ (1, 2, 3), 
              (1, 2, ), 
              [<a b c>, <d e f>], 
              [[1]] ]; 
 for @list -> @element { 
   say "{@element} → {@element.^name}"; 
     for @element -> $sub-element { 
       say $sub-element; 
 #1 2 3 → List 
 #1 2 → List 
 #a b c d e f → Array 
 #(a b c) 
 #(d e f) 
 #1 → Array 

Since what for receives is a single argument, it will be treated as a list of elements to iterate over. The rule of thumb is that if there's a comma, anything preceding it is an element and the list thus created becomes the single element. That happens in the case of the two arrays separated by a comma which are the third in the Array we are iterating. In general, quoting the article linked above, the single argument rule ... makes for behave as the programmer would expect.

Testing for Elements

To test for elements convert the List or Array to a Set or use a Set operator.

my @a = <foo bar buzz>;
say @a.Set<bar buzz>; # OUTPUT: «(True True)␤»
say so 'bar' ∈ @a;    # OUTPUT: «True␤»


Not all lists are born full of elements. Some only create as many elements as they are asked for. These are called sequences, which are of type Seq. As it so happens, loops return Seqs.

(loop { 42.say })[2]  # OUTPUT: «42␤42␤42␤»

So, it is fine to have infinite lists in Perl 6, just so long as you never ask them for all their elements. In some cases, you may want to avoid asking them how long they are too – Perl 6 will try to return Inf if it knows a sequence is infinite, but it cannot always know.

These lists can be built using the ... operator, which builds lazy lists using a variety of generating expressions.

Although the Seq class does provide some positional subscripting, it does not provide the full interface of Positional, so an @-sigiled variable may not be bound to a Seq, and trying to do so will yield an error.

my @s := <a b c>.Seq; CATCH { default { say .^name, ' ', .Str } }
# OUTPUT «X::TypeCheck::Binding Type check failed in binding; expected Positional but got Seq ($(("a", "b","c").Seq))␤»

This is because the Seq does not keep values around after you have used them. This is useful behavior if you have a very long sequence, as you may want to throw values away after using them, so that your program does not fill up memory. For example, when processing a file of a million lines:

for 'filename'.IO.lines -> $line { 

You can be confident that the entire content of the file will not stay around in memory, unless you are explicitly storing the lines somewhere.

On the other hand, you may want to keep old values around in some cases. It is possible to hide a Seq inside a List, which will still be lazy, but will remember old values. This is done by calling the .list method. Since this List fully supports Positional, you may bind it directly to an @-sigiled variable.

my @s := (loop { 42.say }).list;
@s[2]; # says 42 three times
@s[1]; # does not say anything
@s[4]; # says 42 two more times

You may also use the .cache method instead of .list, depending on how you want the references handled. See the page on Seq for details.

TODO document .iterator


Sometimes you want to insert the elements of a list into another list. This can be done with a special type of list called a Slip.

say (1, (2, 3), 4) eqv (1, 2, 3, 4);         # OUTPUT: «False␤»
say (1,, 3), 4) eqv (1, 2, 3, 4); # OUTPUT: «True␤»
say (1, slip(2, 3), 4) eqv (1, 2, 3, 4);     # OUTPUT: «True␤»

Another way to make a Slip is with the | prefix operator. Note that this has a tighter precedence than the comma, so it only affects a single value, but unlike the above options, it will break Scalars.

say (1, |(2, 3), 4) eqv (1, 2, 3, 4);        # OUTPUT: «True␤»
say (1, |$(2, 3), 4) eqv (1, 2, 3, 4);       # OUTPUT: «True␤»
say (1, slip($(2, 3)), 4) eqv (1, 2, 3, 4);  # OUTPUT: «False␤»

Lazy Lists

Lists can be lazy, what means that their values are computed on demand and stored for later use. To create a lazy list use gather/take or the sequence operator. You can also write a class that implements the role Iterable and returns True on a call to is-lazy. Please note that some methods like elems cannot be called on a lazy List and will result in a thrown Exception.

# This list is lazy and elements will not be available
# until explicitly requested.

my @l = lazy 1, 11, 121 ... 10**100;
say;     # OUTPUT: «True␤»
say @l[];           # OUTPUT: «[...]␤»

# Once all elements have been retrieved, the List
# is no longer considered lazy.

my @no-longer-lazy = eager @l;           # Forcing eager evaluation
say;             # OUTPUT: «False␤»
say @no-longer-lazy[];                   # OUTPUT: (sequence starting with «[1 11 121» ending with a 300 digit number)

A common use case for lazy Lists are the processing of infinite sequences of numbers, whose values have not been computed yet and cannot be computed in their entirety. Specific values in the List will only be computed when they are needed.

my @l = 1, 2, 4, 8 ... Inf;
say @l[0..16];
# OUTPUT: «(1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536)␤»


The lists we have talked about so far (List, Seq and Slip) are all immutable. This means you cannot remove elements from them, or re-bind existing elements:

(1, 2, 3)[0]:delete; # Error Can not remove elements from a List 
 (1, 2, 3)[0] := 0;   # Error Cannot use bind operator with this left-hand side 
 (1, 2, 3)[0] = 0;    # Error Cannot modify an immutable Int 

However, if any of the elements is wrapped in a Scalar you can still change the value which that Scalar points to:

my $a = 2;
(1, $a, 3)[1] = 42;
$a.say;            # OUTPUT: «42␤»

...that is, it is only the list structure itself – how many elements there are and each element's identity – that is immutable. The immutability is not contagious past the identity of the element.

List Contexts

So far we have mostly dealt with lists in neutral contexts. Lists are actually very context sensitive on a syntactical level.

List Assignment Context

When a list appears on the right-hand side of an assignment into a @-sigiled variable, it is "eagerly" evaluated. This means that a Seq will be iterated until it can produce no more elements. This is one of the places you do not want to put an infinite list, lest your program hang and, eventually, run out of memory:

my $i = 3;
my @a = (loop { $i.say; last unless --$i }); # OUTPUT: «3␤2␤1␤»
say "take off!";

Flattening "Context"

When you have a list that contains sub-lists, but you only want one flat list, you may flatten the list to produce a sequence of values as if all parentheses were removed. This works no matter how many levels deep the parentheses are nested.

say (1, (2, (3, 4)), 5).flat eqv (1, 2, 3, 4, 5) # OUTPUT: «True␤»

This is not really a syntactical "context" as much as it is a process of iteration, but it has the appearance of a context.

Note that Scalar s around a list will make it immune to flattening:

for (1, (2, $(3, 4)), 5).flat { .say } # OUTPUT: «1␤2␤(3 4)␤5␤»

...but an @-sigiled variable will spill its elements.

my @l := 2, (3, 4);
for (1, @l, 5).flat { .say };      # OUTPUT: «1␤2␤3␤4␤5␤»
my @a = 2, (3, 4);                 # Arrays are special, see below
for (1, @a, 5).flat { .say };      # OUTPUT: «1␤2␤(3 4)␤5␤»

Argument List (Capture) Context

When a list appears as arguments to a function or method call, special syntax rules are at play: the list is immediately converted into a Capture. A Capture itself has a List (.list) and a Hash (.hash). Any Pair literals whose keys are not quoted, or which are not parenthesized, never make it into .list. Instead, they are considered to be named arguments and squashed into .hash. See the page on Capture for the details of this processing.

Consider the following ways to make a new Array from a List. These ways place the List in an argument list context and because of that, the Array only contains 1 and 2 but not the Pair :c(3), which is ignored., 2, :c(3)); 1, 2, :c(3);
new Array: 1, 2, :c(3);

In contrast, these ways do not place the List in argument list context, so all the elements, even the Pair :c(3), are placed in the Array., 2, :c(3)));
(1, 2, :c(3)).Array;
my @a = 1, 2, :c(3);;
my @a = 1, 2, :c(3); @a;
my @a = 1, 2, :c(3); new Array: @a;

In argument list context the | prefix operator applied to a Positional will always slip list elements as positional arguments to the Capture, while a | prefix operator applied to an Associative will slip pairs in as named parameters:

my @a := 2, "c" => 3;, |@a, 4);    # Array contains 1, 2, :c(3), 4
my %a = "c" => 3;, |%a, 4);    # Array contains 1, 4

Slice Indexing Context

From the perspective of the List inside a slice subscript, is only remarkable in that it is unremarkable: because adverbs to a slice are attached after the ], the inside of a slice is not an argument list, and no special processing of pair forms happens.

Most Positional types will enforce an integer coercion on each element of a slice index, so pairs appearing there will generate an error, anyway:

(1, 2, 3)[1, 2, :c(3)] # OUTPUT: «Method 'Int' not found for invocant of class 'Pair'␤» 

...however this is entirely up to the type – if it defines an order for pairs, it could consider :c(3) a valid index.

Indices inside a slice are usually not automatically flattened, but neither are sublists usually coerced to Int. Instead, the list structure is kept intact, causing a nested slice operation that replicates the structure in the result:

say ("a", "b", "c")[(1, 2), (0, 1)] eqv (("b", "c"), ("a", "b")) # OUTPUT: «True␤»

Slices can be taken also across several dimensions using semilists, which are lists of slices separated by semicolons:

my @sliceable = [[ ^10 ], ['a'..'h'], ['Ⅰ'..'Ⅺ']];
say @sliceable[ ^3; 4..6 ]; #OUTPUT: «(4 5 6 e f g Ⅴ Ⅵ Ⅶ)␤»

which is selecting the 4 to 6th element from the three first dimensions (^3).

Range as Slice

A Range is a container for a lower and a upper boundary. Generating a slice with a Range will include any index between those bounds, including the bounds. For infinite upper boundaries we agree with mathematicians that Inf equals Inf-1.

my @a = 1..5;
say @a[0..2];     # OUTPUT: «(1 2 3)␤»
say @a[0..^2];    # OUTPUT: «(1 2)␤»
say @a[0..*];     # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..^*];    # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..Inf-1]; # OUTPUT: «(1 2 3 4 5)␤»

Array Constructor Context

Inside an Array Literal, the list of initialization values is not in capture context and is just a normal list. It is, however, eagerly evaluated just as in assignment.

say so [ 1, 2, :c(3) ] eqv, 2, :c(3))); # OUTPUT: «True␤»
[while $++ < 2 { 42.say; 43 }].map: *.say;           # OUTPUT: «42␤42␤43␤43␤»
(while $++ < 2 { 42.say; 43 }).map: *.say;           # OUTPUT: «42␤43␤42␤43␤»

Which brings us to Arrays...


Arrays differ from lists in three major ways: Their elements may be typed, they automatically itemize their elements, and they are mutable. Otherwise they are Lists and are accepted wherever lists are.

say Array ~~ List     # OUTPUT: «True␤»

A fourth, more subtle, way they differ is that when working with Arrays, it can sometimes be harder to maintain laziness or work with infinite sequences.


Arrays may be typed such that their slots perform a typecheck whenever they are assigned to. An Array that only allows Int values to be assigned is of type Array[Int] and one can create one with Array[Int].new. If you intend to use an @-sigiled variable only for this purpose, you may change its type by specifying the type of the elements when declaring it:

my Int @a = 1, 2, 3;              # An Array that contains only Ints 
 my @b := Array[Int].new(1, 2, 3); # Same thing, but the variable is not typed 
 say @b eqv @a;                    # says True. 
 my @c = 1, 2, 3;                  # An Array that can contain anything 
 say @b eqv @c;                    # says False because types do not match 
 say @c eqv (1, 2, 3);             # says False because one is a List 
 say @b eq @c;                     # says True, because eq only checks values 
 say @b eq (1, 2, 3);              # says True, because eq only checks values 
 @a[0] = 42;                       # fine 
 @a[0] = "foo";                    # error: Type check failed in assignment 

In the above example we bound a typed Array object to a @-sigil variable for which no type had been specified. The other way around does not work – you may not bind an Array that has the wrong type to a typed @-sigiled variable:

my @a := Array[Int].new(1, 2, 3);     # fine 
 @a := Array[Str].new("a", "b");       # fine, can be re-bound 
 my Int @b := Array[Int].new(1, 2, 3); # fine 
 @b :=, 2, 3);             # error: Type check failed in binding 

When working with typed arrays, it is important to remember that they are nominally typed. This means the declared type of an array is what matters. Given the following sub declaration:

sub mean(Int @a) {
    @a.sum / @a.elems

Calls that pass an Array[Int] will be successful:

my Int @b = 1, 3, 5; 
 say mean(@b);                       # @b is Array[Int] 
 say mean(Array[Int].new(1, 3, 5));  # Anonymous Array[Int] 
 say mean(my Int @ = 1, 3, 5);       # Another anonymous Array[Int] 

However, the following calls will all fail, due to passing an untyped array, even if the array just happens to contain Int values at the point it is passed:

my @c = 1, 3, 5; 
 say mean(@c);                       # Fails, passing untyped Array 
 say mean([1, 3, 5]);                # Same 
 say mean(, 3, 5));       # Same again 

Note that in any given compiler, there may be fancy, under-the-hood, ways to bypass the type check on arrays, so when handling untrusted input, it can be good practice to perform additional type checks, where it matters:

for @a -> Int $i { $_++.say }; 

However, as long as you stick to normal assignment operations inside a trusted area of code, this will not be a problem, and typecheck errors will happen promptly during assignment to the array, if they cannot be caught at compile time. None of the core functions provided in Perl 6 for operating on lists should ever produce a wonky typed Array.

Nonexistent elements (when indexed), or elements to which Nil has been assigned, will assume a default value. This default may be adjusted on a variable-by-variable basis with the is default trait. Note that an untyped @-sigiled variable has an element type of Mu, however its default value is an undefined Any:

my @a;
@a.of.perl.say;                 # OUTPUT: «Mu␤»
@a.default.perl.say;            # OUTPUT: «Any␤»
@a[0].say;                      # OUTPUT: «(Any)␤»
my Numeric @n is default(Real);
@n.of.perl.say;                 # OUTPUT: «Numeric␤»
@n.default.perl.say;            # OUTPUT: «Real␤»
@n[0].say;                      # OUTPUT: «(Real)␤»

Fixed Size Arrays

To limit the dimensions of an Array provide the dimensions separated by , or ; in brackets after the name of the array container. The values of such an Arrays will default to Any. The shape can be accessed at runtime via the shape method.

my @a[2,2];
say @a.perl;
# OUTPUT: «, 2), [Any, Any], [Any, Any])␤»
say @a.shape;
# OUTPUT: «(2 2)␤»

Assignment to a fixed size Array will promote a List of Lists to an Array of Arrays.

my @a[2;2] = (1,2; 3,4);
@a[1;1] = 42;
say @a.perl;
# OUTPUT: «, 2), [1, 2], [3, 42])␤»


For most uses, Arrays consist of a number of slots each containing a Scalar of the correct type. Each such Scalar, in turn, contains a value of that type. Perl 6 will automatically type-check values and create Scalars to contain them when Arrays are initialized, assigned to, or constructed.

This is actually one of the trickiest parts of Perl 6 list handling to get a firm understanding of.

First, be aware that because itemization in Arrays is assumed, it essentially means that $(…)s are being put around everything that you assign to an array, if you do not put them there yourself. On the other side, Array.perl does not put $ to explicitly show scalars, unlike List.perl:

((1, 2), $(3, 4)).perl.say; # says "((1, 2), $(3, 4))"
[(1, 2), $(3, 4)].perl.say; # says "[(1, 2), (3, 4)]"
                            # ...but actually means: "[$(1, 2), $(3, 4)]"

It was decided all those extra dollar signs and parentheses were more of an eye sore than a benefit to the user. Basically, when you see a square bracket, remember the invisible dollar signs.

Second, remember that these invisible dollar signs also protect against flattening, so you cannot really flatten the elements inside of an Array with a normal call to flat or .flat.

((1, 2), $(3, 4)).flat.perl.say; # OUTPUT: «(1, 2, $(3, 4)).Seq␤»
[(1, 2), $(3, 4)].flat.perl.say; # OUTPUT: «($(1, 2), $(3, 4)).Seq␤»

Since the square brackets do not themselves protect against flattening, you can still spill the elements out of an Array into a surrounding list using flat.

(0, [(1, 2), $(3, 4)], 5).flat.perl.say; # OUTPUT: «(0, $(1, 2), $(3, 4), 5).Seq␤»

...the elements themselves, however, stay in one piece.

This can irk users of data you provide if you have deeply nested Arrays where they want flat data. Currently they have to deeply map the structure by hand to undo the nesting:

say gather [0, [(1, 2), [3, 4]], $(5, 6)].deepmap: *.take; # OUTPUT: «(1 2 3 4 5 6)␤»

...future versions of Perl 6 might find a way to make this easier. However, not returning Arrays or itemized lists from functions, when non-itemized lists are sufficient, is something that one should consider as a courtesy to their users:

The fact that all elements of an array are itemized (in Scalar containers) is more a gentleman's agreement than a universally enforced rule, and it is less well enforced that typechecks in typed arrays. See the section below on binding to Array slots.

Literal Arrays

Literal Arrays are constructed with a List inside square brackets. The List is eagerly iterated (at compile time if possible) and values in the list are each type-checked and itemized. The square brackets themselves will spill elements into surrounding lists when flattened, but the elements themselves will not spill due to the itemization.


Unlike lists, Arrays are mutable. Elements may deleted, added, or changed.

my @a = "a", "b", "c";
@a.say;                  # OUTPUT: «[a b c]␤»
@a.pop.say;              # OUTPUT: «c␤»
@a.say;                  # OUTPUT: «[a b]␤»
@a.say;                  # OUTPUT: «[a b d]␤»
@a[1, 3] = "c", "c";
@a.say;                  # OUTPUT: «[a c d c]␤»


Assignment of a list to an Array is eager. The list will be entirely evaluated, and should not be infinite or the program may hang. Assignment to a slice of an Array is, likewise, eager, but only up to the requested number of elements, which may be finite:

my @a;
@a[0, 1, 2] = (loop { 42 });
@a.say;                     # OUTPUT: «[42 42 42]␤»

During assignment, each value will be typechecked to ensure it is a permitted type for the Array. Any Scalar will be stripped from each value and a new Scalar will be wrapped around it.


Individual Array slots may be bound the same way $-sigiled variables are:

my $b = "foo";
my @a = 1, 2, 3;
@a[2] := $b;
@a.say;          # OUTPUT: «[1 2 "foo"]␤»
$b = "bar";
@a.say;          # OUTPUT: «[1 2 "bar"]␤»

...but binding Array slots directly to values is strongly discouraged. If you do, expect surprises with built-in functions. The only time this would be done is if a mutable container that knows the difference between values and Scalar-wrapped values is needed, or for very large Arrays where a native-typed array cannot be used. Such a creature should never be passed back to unsuspecting users.

26 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: «␤»

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

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

NativeCall modules

Other modules

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

29 Modules

How to create, use and distribute Perl 6 modules

Creating and Using Modules

A module is usually a source file or set of source files

Technically a module is a set of compunits which are usually files but could come from anywhere as long as there is a compunit repository that can provide it. See S11 .
that expose Perl 6 constructs. These are typically packages (classes, roles, grammars), subroutines, and sometimes variables. In Perl 6 module can also refer to a type of package declared with the module keyword (see Module Packages and the examples below) but here we mostly mean "module" as a set of source files in a namespace.

Looking for and installing modules.

zef is the application using for installing modules in Perl 6. Modules are listed in the Perl 6 ecosystem and can be searched there or from the command line using zef search

    zef search WWW 

will return a list of modules that includes WWW in their name, for instance. Then,

    zef install WWW 

will install the module with that particular name, if it is not already installed.

Basic Structure

Module distributions (in the set of related source files sense) in Perl 6 have the same structure as any distribution in the Perl family of languages: there is a main project directory containing a README and a LICENSE file, a lib directory for the source files, which may be individually referred to as modules and/or may themselves define modules with the module keyword

As synopsis S11 says: Confusing? Yes it is.
, a t directory for tests, and possibly a bin directory for executable programs and scripts.

Source files generally use the .pm6 extension, and scripts or executables use the .p6. Test files use the .t extension. Files which contain documentation use the .pod6 extension.

Loading and Basic Importing

Loading a module makes the packages in the same namespace declared within available in the file scope of the loader. Importing from a module makes the symbols exported available in the lexical scope of the importing statement.


need loads a compunit at compile time.

need MyModule; 

Any packages in the namespace defined within will also be available.

# MyModule.pm6 
 unit module MyModule; 
 class MyModule::Class {} 

MyModule::Class will be defined when MyModule is loaded.

class Class { ... } won't get exported automatically on loading...not sure if bug or..


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

use MyModule; 

It is equivalent to:

need  MyModule; 
 import MyModule; 

See also Selective Importing to restrict what you import.


require 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 run-time symbol lookup with require, to avoid compile-time
# package installation:
try require ::('Foo');
if ::('Foo') ~~ Failure {
    say "Failed to load Foo!";

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 (>; 
 our $var is export = 3; 
 sub foo is export { ... }; 
 constant FOO is export = "foobar"; 
 enum FooBar is export <one two three>; 
 # Packages like classes can be exported too 
 class MyClass is export {}; 
 # If a subpackage is in the namespace of the current package 
 # it doesn't need to be explicitly exported 
 class MyModule::MyClass {}; 

As with all traits, if applied to a routine, "is export" should appear after any argument list.

sub foo(Str $string) is export { ... } 

You can pass named parameters to is export to group symbols for exporting so that the importer can pick and choose. There are three predefined tags: ALL, DEFAULT and MANDATORY.

# lib/MyModule.pm6 
 unit module MyModule; 
 sub bag        is export             { ... } 
 sub pants      is export(:MANDATORY) { ... } # objects with tag ':MANDATORY' are always exported 
 sub sunglasses is export(:day)       { ... } 
 sub torch      is export(:night)     { ... } 
 sub underpants is export(:ALL)       { ... } 
# main.p6 
 use lib 'lib'; 
 use MyModule;          # bag, pants 
 use MyModule :DEFAULT; # the same 
 use MyModule :day;     # pants, sunglasses 
 use MyModule :night;   # pants, torch 
 use MyModule :ALL;     # bag, pants, sunglasses, torch, underpants 

Note there currently is no way for the user to import a single object if the module author hasn't made provision for that, and it is not an easy task at the moment (see RT #127305). One way the author can provide such access is to give each export trait its own unique tag. (And the tag can be the object name!) Then the user can either (1) import all objects:

use Foo :ALL; 

or (2) import one or more objects selectively:

use Foo :bar, :s5; 


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; # OUTPUT: «␤» 

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; # OUTPUT: «␤» 
 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>;

Finding Modules

It is up to the module installer to know where compunit expects modules to be placed. There will be a location provided by the distribution and in the current home directory. In any case, letting the module installer deal with your modules is a safe bet.

cd your-module-dir 
 zef --force install . 

A user may have a collection of modules not found in the normal ecosystem, maintained by a module or package manager, but needed regularly. Instead of using the use lib pragma one can use the PERL6LIB environment variable to point to module locations. For example:

export PERL6LIB=/path/to/my-modules,/path/to/more/modules 

Note that the comma (',') is used as the directory separator.

The include path will be searched recursively for any modules when Rakudo is started. Directories that start with a dot are ignored and symlinks are followed.

Distributing Modules

If you've written a Perl 6 module and would like to share it with the community, we'd be delighted to have it listed in the Perl 6 modules directory. :)

Currently there are two different module ecosystems (module distribution networks) available:

The process of sharing your module consists of two steps, preparing the module and uploading the module to one of the ecosystems.

Preparing the Module

For a module to work in any of the ecosystems, it needs to follow a certain structure. Here is how to do that:

Upload your Module to CPAN

Uploading a module to CPAN is the preferred way of distributing Perl 6 modules.

it requires having a PAUSE user account. If you don't have an account already go there and apply for an account. The process takes about 5 minutes and some e-mail back and forth.

Upload your Module to p6c

If you want to use the p6c ecosystem you need to use git for your module's version control. The instructions herein assume that you have a GitHub account so that your module can be shared from its GitHub repository, however another provider such as GitLab should work as long as it works in a similar way.

That's it! Thanks for contributing to the Perl 6 community!

If you'd like to try out installing your module, use the zef module installer tool which is included with Rakudo Star Perl 6:

zef install Vortex::TotalPerspective 

This will download your module to its own working directory (~/.zef), build it there, and install the module into your local Perl 6 installation directory.

To use Vortex::TotalPerspective from your scripts, just write use Vortex::TotalPerspective, and your Perl 6 implementation will know where to look for the module file(s).

Modules and Tools Related to Module Authoring

You can find a list of modules and tools that aim to improve the experience of writing/test modules at Modules Extra

Contact Information

To discuss module development in general, or if your module would fill a need in the ecosystem, naming, etc., you can use the #perl6 on IRC channel.

To discuss toolchain specific questions, you can use the #perl6-toolchain on IRC channel. A repository to discuss tooling issues is also available at

30 Meta-Object Protocol

Introspection and the Perl 6 Object System

Perl 6 is built on a meta object layer. That means that there are objects (the meta objects) that control how various object-oriented constructs (such as classes, roles, methods, attributes, enums, ...) behave.

To get a feeling for the meta object for class, here is the same example twice: once as normal declarations in Perl 6, and once expressed through the meta model:

class A {
    method x() { say 42 }


corresponds to:

constant A := Metamodel::ClassHOW.new_type( name => 'A' );  # class A {
A.^add_method('x', my method x(A:) { say 42 });             # method x() .. .
A.^compose;                                                 # }


(except that the declarative form runs at compile time, and the latter form does not).

The meta object behind an object can be obtained with $obj.HOW, where HOW stands for Higher Order Workings (or, HOW the *%@$ does this work?).

Here, the calls with .^ are calls to the meta object, so A.^compose is a shortcut for A.HOW.compose(A). The invocant is passed in the parameter list as well, to make it possible to support prototype-style type systems, where there is just one meta object (and not one meta object per type, as standard Perl 6 does it).

As the example above demonstrates, all object oriented features are available to the user, not just to the compiler. In fact the compiler just uses such calls to meta objects.


These are introspective macros that resemble method calls.

Metamethods are generally named with ALLCAPS, and it is considered good style to avoid creating your own methods with ALLCAPS names. This will avoid conflicts with any metamethods that may appear in future versions of the language.


The type object of the type. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

For example 42.WHAT returns the Int type object.


The object's identity value. This can be used for hashing and identity comparison, and is how the === infix operator is implemented.


The package supporting the object.


The memory address of the object. Note that this is not stable in implementations with moving/compacting garbage collectors. Use WHICH for a stable identity indicator.


The metaclass object: "Higher Order Workings".


The attached Pod value.


The object has a valid concrete representation. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

Returns True for instances and False for type objects.


Returns the underlying Scalar object, if there is one.

The presence of a Scalar object indicates that the object is "itemized".

.say for (1, 2, 3);           # OUTPUT: «1␤2␤3␤», not itemized
.say for $(1, 2, 3);          # OUTPUT: «(1 2 3)␤», itemized
say (1, 2, 3).VAR ~~ Scalar;  # OUTPUT: «False␤»
say $(1, 2, 3).VAR ~~ Scalar; # OUTPUT: «True␤»

Structure of the meta object system

Note: this documentation largely reflects the meta object system as implemented by the Rakudo Perl 6 compiler, since the design documents are very light on details.

For each type declarator keyword, such as class, role, enum, module, package, grammar or subset, there is a separate meta class in the Metamodel:: namespace. (Rakudo implements them in the Perl6::Metamodel:: namespace, and then maps Perl6::Metamodel to Metamodel).

Many of the these meta classes share common functionality. For example roles, grammars and classes can all contain methods and attributes, as well as being able to do roles. This shared functionality is implemented in roles which are composed into the appropriate meta classes. For example role Metamodel::RoleContainer implements the functionality that a type can hold roles and Metamodel::ClassHOW, which is the meta class behind the class keyword, does this role.

Most meta classes have a compose method that you must call when you're done creating or modifying a meta object. It creates method caches, validates things and so on, and weird behavior ensues if you forget to call it, so don't :-).

Bootstrapping concerns

You might wonder how Metamodel::ClassHOW can be a class, when being a class is defined in terms of Metamodel::ClassHOW, or how the roles responsible for role handling can be roles. The answer is by magic.

Just kidding. Bootstrapping is implementation specific. Rakudo does it by using the object system of the language in which itself is implemented, which happens to be (nearly) a subset of Perl 6: NQP, Not Quite Perl. NQP has a primitive, class-like kind called knowhow, which is used to bootstrap its own classes and roles implementation. knowhow is built on primitives that the virtual machine under NQP provides.

Since the object model is bootstrapped in terms of lower-level types, introspection can sometimes return low-level types instead of the ones you expect, like an NQP-level routine instead of a normal Routine object, or a bootstrap-attribute instead of Attribute.

Composition time and static reasoning

In Perl 6, a type is constructed as it is parsed, so in the beginning, it must be mutable. However if all types were always mutable, all reasoning about them would get invalidated at any modification of a type. For example the list of parent types and thus the result of type checking can change during that time.

So to get the best of both worlds, there is a time when a type transitions from mutable to immutable. This is called composition, and for syntactically declared types, it happens when the type declaration is fully parsed (so usually when the closing curly brace is parsed).

If you create types through the meta-object system directly, you must call .^compose on them before they become fully functional.

Most meta classes also use composition time to calculate some properties like the method resolution order, publish a method cache, and other house-keeping tasks. Meddling with types after they have been composed is sometimes possible, but usually a recipe for disaster. Don't do it.

Power and Responsibility

The meta object protocol offers much power that regular Perl 6 code intentionally limits, such as calling private methods on classes that don't trust you, peeking into private attributes, and other things that usually simply aren't done.

Regular Perl 6 code has many safety checks in place; not so the meta model. It is close to the underlying virtual machine, and violating the contracts with the VM can lead to all sorts of strange behaviors that, in normal code, would obviously be bugs.

So be extra careful and thoughtful when writing meta types.

Power, Convenience and Pitfalls

The meta object protocol is designed to be powerful enough to implement the Perl 6 object system. This power occasionally comes at the cost of convenience.

For example, when you write my $x = 42 and then proceed to call methods on $x, most of these methods end up acting on the integer 42, not on the scalar container in which it is stored. This is a piece of convenience found in ordinary Perl 6. Many parts of the meta object protocol cannot afford to offer the convenience of automatically ignoring scalar containers, because they are used to implement those scalar containers as well. So if you write my $t = MyType; ... ; $t.^compose you are composing the Scalar that the $-sigiled variable implies, not MyType.

The consequence is that you need to have a rather detailed understanding of the subtleties of Perl 6 in order to avoid pitfalls when working with the MOP, and can't expect the same "do what I mean" convenience that ordinary Perl 6 code offers.

31 Native Calling Interface

Call into dynamic libraries that follow the C calling convention

Getting Started

The simplest imaginable use of NativeCall would look something like this:

use NativeCall;
sub some_argless_function() is native('something') { * }

The first line imports various traits and types. The next line looks like a relatively ordinary Perl 6 sub declaration—with a twist. We use the "native" trait in order to specify that the sub is actually defined in a native library. The platform-specific extension (e.g., '.so' or '.dll'), as well as any customary prefixes (e.g., 'lib') will be added for you.

The first time you call "some_argless_function", the "libsomething" will be loaded and the "some_argless_function" will be located in it. A call will then be made. Subsequent calls will be faster, since the symbol handle is retained.

Of course, most functions take arguments or return values—but everything else that you can do is just adding to this simple pattern of declaring a Perl 6 sub, naming it after the symbol you want to call and marking it with the "native" trait.

Changing names

Sometimes you want the name of your Perl subroutine to be different from the name used in the library you're loading. Maybe the name is long or has different casing or is otherwise cumbersome within the context of the module you are trying to create.

NativeCall provides a "symbol" trait for you to specify the name of the native routine in your library that may be different from your Perl subroutine name.

unit module Foo; 
 use NativeCall; 
 our sub init() is native('foo') is symbol('FOO_INIT') { * } 

Inside of "libfoo" there is a routine called "FOO_INIT" but, since we're creating a module called Foo and we'd rather call the routine as Foo::init, we use the "symbol" trait to specify the name of the symbol in "libfoo" and call the subroutine whatever we want ("init" in this case).

Passing and Returning Values

Normal Perl 6 signatures and the returns trait are used in order to convey the type of arguments a native function expects and what it returns. Here is an example.

use NativeCall;
sub add(int32, int32) returns int32 is native("calculator") { * }

Here, we have declared that the function takes two 32-bit integers and returns a 32-bit integer. Here are some of the other types that you may pass (this will likely grow with time).

int (long in C)
int8 (int8_t in C, also used for char)
int16 (int16_t in C, also used for short)
int32 (int32_t in C, also used for int)
int64 (int64_t in C)
uint (ulong in C)
uint8 (uint8_t in C, also used for unsigned char)
uint16 (uint16_t in C, also used for unsigned short)
uint32 (uint32_t in C, also used for unsigned int)
uint64 (uint64_t in C)
long (long in C)
longlong (long long in C, at least 64-bit)
ulong (unsigned long in C)
ulonglong (unsigned long long in C, at least 64-bit)
longdouble (longdouble in C)
Num, num (double in C)
num32 (float in C)
num64 (double in C)
Str (C string)
CArray[int32] (int32_t* in C, an array of 32-bit ints)
Pointer[void] (void* in C, can point to all other types)
bool (bool from C99)
size_t (size_t in C)
ssize_t (ssize_t in C)
Callable (callback in C)

Don't use Perl 6 native types like int or num in native calls, as they don't have to correspond to the local C equivalent (e.g., Perl 6's int can be 8 bytes but C's int is only 4 bytes).

Note that the lack of a returns trait is used to indicate void return type. Do not use the 'void' type anywhere except in the Pointer parameterization.

For strings, there is an additional "encoded" trait to give some extra hints on how to do the marshaling.

use NativeCall;
sub message_box(Str is encoded('utf8')) is native('gui') { * }

To specify how to marshal string return types, just apply this trait to the routine itself.

use NativeCall;
sub input_box() returns Str is encoded('utf8') is native('gui') { * }

Note that a NULL string pointer can be passed by passing the Str type object; a NULL return will also be represented by the type object.

If the C function requires the lifetime of a string to exceed the function call, the argument must be manually encoded and passed as CArray[uint8]:

use NativeCall;
# C prototype is void set_foo(const char *)
sub set_foo(CArray[uint8]) is native('foo') { * }
# C prototype is void use_foo(void)
sub use_foo() is native('foo') { * } # will use pointer stored by set_foo()

my $string = "FOO";
# The lifetime of this variable must be equal to the required lifetime of
# the data passed to the C function.
my $array = CArray[uint8].new($string.encode.list);

# ...
# It's fine if $array goes out of scope starting from here.

Specifying the native representation

When working with native functions, sometimes you need to specify what kind of native data structure is going to be used. is repr is the term employed for that.

use NativeCall; 
 class timespec is repr('CStruct') { 
     has uint32 $.tv_sec; 
     has long $.tv_nanosecs; 
 sub clock_gettime(uint32 $clock-id, timespec $tspec --> uint32) is native { * }; 
 my timespec $this-time .=new; 
 my $result = clock_gettime( 0, $this-time); 
 say "$result, $this-time"; # OUTPUT: «0, timespec<65385480>␤» 

The original function we are calling, clock_gettime, uses a pointer to the timespec struct as second argument. We declare it as a class here, but specify its representation as is repr('CStruct'), to indicate it corresponds to a C data structure. When we create an object of that class, we are creating exactly the kind of pointer clock_gettime expects. This way, data can be transferred seamlessly to and from the native interface.

Basic use of Pointers

When the signature of your native function needs a pointer to some native type (int32, uint32, etc.) all you need to do is declare the argument is rw :

use NativeCall;
# C prototype is void my_version(int *major, int *minor)
sub my_version(int32 is rw, int32 is rw) is native('foo') { * }
my_version(my int32 $major, my int32 $minor); # Pass a pointer to

Sometimes you need to get a pointer (for example, a library handle) back from a C library. You don't care about what it points to - you just need to keep hold of it. The Pointer type provides for this.

use NativeCall;
sub Foo_init() returns Pointer is native("foo") { * }
sub Foo_free(Pointer) is native("foo") { * }

This works out OK, but you may fancy working with a type named something better than Pointer. It turns out that any class with the representation "CPointer" can serve this role. This means you can expose libraries that work on handles by writing a class like this:

use NativeCall; 
 class FooHandle is repr('CPointer') { 
     # Here are the actual NativeCall functions. 
     sub Foo_init() returns FooHandle is native("foo") { * } 
     sub Foo_free(FooHandle) is native("foo") { * } 
     sub Foo_query(FooHandle, Str) returns int8 is native("foo") { * } 
     sub Foo_close(FooHandle) returns int8 is native("foo") { * } 
     # Here are the methods we use to expose it to the outside world. 
     method new { 
     method query(Str $stmt) { 
         Foo_query(self, $stmt); 
     method close { 
     # Free data when the object is garbage collected. 
     submethod DESTROY { 

Note that the CPointer representation can do nothing more than hold a C pointer. This means that your class cannot have extra attributes. However, for simple libraries this may be a neat way to expose an object oriented interface to it.

Of course, you can always have an empty class:

class DoorHandle is repr('CPointer') { }

And just use the class as you would use Pointer, but with potential for better type safety and more readable code.

Once again, type objects are used to represent NULL pointers.

Function Pointers

C libraries can expose pointers to C functions as return values of functions and as members of Structures like, e.g., structs and unions.

Example of invoking a function pointer "$fptr" returned by a function "f", using a signature defining the desired function parameters and return value:

sub f() returns Pointer is native('mylib') { * } 
 my $fptr    = f(); 
 my &newfunc = nativecast(:(Str, size_t --> int32), $fptr); 
 say newfunc("test", 4); 


NativeCall has some support for arrays. It is constrained to work with machine-size integers, doubles and strings, sized numeric types, arrays of pointers, arrays of structs, and arrays of arrays.

Perl 6 arrays, which support amongst other things laziness, are laid out in memory in a radically different way to C arrays. Therefore, the NativeCall library offers a much more primitive CArray type, which you must use if working with C arrays.

Here is an example of passing a C array.

sub RenderBarChart(Str, int32, CArray[Str], CArray[num64]) is native("chart") { * } 
 my @titles := CArray[Str].new; 
 @titles[0]  = 'Me'; 
 @titles[1]  = 'You'; 
 @titles[2]  = 'Hagrid'; 
 my @values := CArray[num64].new; 
 @values[0]  = 59.5e0; 
 @values[1]  = 61.2e0; 
 @values[2]  = 180.7e0; 
 RenderBarChart('Weights (kg)', 3, @titles, @values); 

Note that binding was used to @titles, not assignment! If you assign, you are putting the values into a Perl 6 array, and it will not work out. If this all freaks you out, forget you ever knew anything about the @ sigil and just use $ all the way when using NativeCall.

use NativeCall;
my $titles = CArray[Str].new;
$titles[0] = 'Me';
$titles[1] = 'You';
$titles[2] = 'Hagrid';

Getting return values for arrays works out just the same.

Some library APIs may take an array as a buffer that will be populated by the C function and, for instance, return the actual number of items populated:

use NativeCall;
sub get_n_ints(CArray[int32], int32) returns int32 is native('ints') { * }

In these cases it is important that the CArray has at least the number of elements that are going to be populated before passing it to the native subroutine, otherwise the C function may stomp all over Perl's memory leading to possibly unpredictable behaviour:

my $number_of_ints = 10; 
 my $ints = CArray[int32].allocate($number_of_ints); # instantiates an array with 10 elements 
 my $n = get_n_ints($ints, $number_of_ints); 

The memory management of arrays is important to understand. When you create an array yourself, then you can add elements to it as you wish and it will be expanded for you as required. However, this may result in it being moved in memory (assignments to existing elements will never cause this, however). This means you'd best know what you're doing if you twiddle with an array after passing it to a C library.

By contrast, when a C library returns an array to you, then the memory can not be managed by NativeCall, and it doesn't know where the array ends. Presumably, something in the library API tells you this (for example, you know that when you see a null element, you should read no further). Note that NativeCall can offer you no protection whatsoever here - do the wrong thing, and you will get a segfault or cause memory corruption. This isn't a shortcoming of NativeCall, it's the way the big bad native world works. Scared? Here, have a hug. Good luck!

CArray methods

Besides the usual methods available on every Perl 6 instance, CArray provides the following methods that can be used to interact with the it from the Perl 6 point of view:

As an example, consider the following simple piece of code:

use NativeCall; 
 my $native-array = CArray[int32].new( 1, 2, 3, 4, 5 ); 
 say 'Number of elements: ' ~ $native-array.elems; 
 # walk the array 
 for $native-array.list -> $elem { 
     say "Current element is: $elem"; 
 # get every element by its index-based position 
 for 0..$native-array.elems - 1 -> $position { 
     say "Element at position $position is " 
           ~ $native-array.AT-POS( $position ); 

that produces the following output

  Number of elements: 5 
   Current element is: 1 
   Current element is: 2 
   Current element is: 3 
   Current element is: 4 
   Current element is: 5 
   Element at position 0 is 1 
   Element at position 1 is 2 
   Element at position 2 is 3 
   Element at position 3 is 4 
   Element at position 4 is 5 


Thanks to representation polymorphism, it's possible to declare a normal looking Perl 6 class that, under the hood, stores its attributes in the same way a C compiler would lay them out in a similar struct definition. All it takes is a quick use of the "repr" trait:

class Point is repr('CStruct') {
    has num64 $.x;
    has num64 $.y;

The attributes can only be of the types that NativeCall knows how to marshal into struct fields. Currently, structs can contain machine-sized integers, doubles, strings, and other NativeCall objects (CArrays, and those using the CPointer and CStruct reprs). Other than that, you can do the usual set of things you would with a class; you could even have some of the attributes come from roles or have them inherited from another class. Of course, methods are completely fine too. Go wild!

CStruct objects are passed to native functions by reference and native functions must also return CStruct objects by reference. The memory management rules for these references are very much like the rules for arrays, though simpler since a struct is never resized. When you create a struct, the memory is managed for you and when the variable(s) pointing to the instance of a CStruct go away, the memory will be freed when the GC gets to it. When a CStruct-based type is used as the return type of a native function, the memory is not managed for you by the GC.

NativeCall currently doesn't put object members in containers, so assigning new values to them (with =) doesn't work. Instead, you have to bind new values to the private members:

class MyStruct is repr('CStruct') { 
     has CArray[num64] $!arr; 
     has Str $!str; 
     has Point $!point; # Point is a user-defined class 
     submethod TWEAK { 
         my $arr := CArray[num64].new; 
         $arr[0] = 0.9e0; 
         $arr[1] = 0.2e0; 
         $!arr := $arr; 
         $!str := 'Perl 6 is fun'; 
         $!point :=; 

As you may have predicted by now, a NULL pointer is represented by the type object of the struct type.


Likewise, it is possible to declare a Perl 6 class that stores its attributes the same way a C compiler would lay them out in a similar union definition; using the CUnion representation:

use NativeCall; 
 class MyUnion is repr('CUnion') { 
     has int32 $.flags32; 
     has int64 $.flags64; 
 say nativesizeof(;  # 8, ie. max(sizeof(MyUnion.flags32), sizeof(MyUnion.flags64)) 

Embedding CStructs and CUnions

CStructs and CUnions can be in turn referenced by—or embedded into—a surrounding CStruct and CUnion. To say the former we use has as usual, and to do the latter we use the HAS declarator instead:

class MyStruct is repr('CStruct') { 
     has Point $.point;  # referenced 
     has int32 $.flags; 
 say nativesizeof(;  # 16, ie. sizeof(struct Point *) + sizeof(int32_t) 
 class MyStruct2 is repr('CStruct') { 
     HAS Point $.point;  # embedded 
     has int32 $.flags; 
 say nativesizeof(;  # 24, ie. sizeof(struct Point) + sizeof(int32_t) 

Notes on Memory management

When allocating a struct for use as a struct, make sure that you allocate your own memory in your C functions. If you're passing a struct into a C function which needs a Str/char* allocated ahead of time, be sure to assign a container for a variable of type Str prior to passing your struct into the function.

In your Perl6 code...

class AStringAndAnInt is repr("CStruct") { 
   has Str $.a_string; 
   has int32 $.an_int32; 
   submethod TWEAK { 
     $!a_string :=; 
     $!an_int32 = 0; 
   sub init_struct(AStringAndAnInt is rw, Str, int32) is native('simple-struct') { * } 
   method init(:$a_string, :$an_int) { 
     init_struct(self, $a_string, $an_int); 

In this code we first set up our members, $.a_string and $.an_int32. We then set the container of $.a_string to a new Str. After that we declare our init_struct() function for the init() method to wrap around.

In your C code...

typedef struct a_string_and_an_int32_t_ { 
   char *a_string; 
   int32_t an_int32; 
 } a_string_and_an_int32_t; 

Here's the structure. Notice how we've got a char * there.

void init_struct(a_string_and_an_int32_t *target, char *str, int32_t int32) { 
   target->an_int32 = int32; 
   target->a_string = strdup(str); 

In this function we initialize the C structure by assigning an integer by value, and passing the string by reference. The function allocates memory that it points <char *a_string> to within the structure as it copies the string. (Note you will also have to manage deallocation of the memory as well to avoid memory leaks.)

# A long time ago in a galaxy far, far away...

my $foo =; 
 $foo.init(a_string => "str", an_int => 123); 

Typed Pointers


TBD more

You can type your Pointer by passing the type as a parameter. It works with the native type but also with CArray and CStruct defined types. NativeCall will not implicitly allocate the memory for it even when calling new on them. It's mostly useful in the case of a C routine returning a pointer, or if it's a pointer embedded in a CStruct.

You have to call .deref on Pointers to access the embedded type.

my Pointer[int32] $p; #For a pointer on int32; 
 my Pointer[MyCstruct] $p2 = some_c_routine(); 
 my MyCstruct $mc = $p2.deref; 
 say $mc.field1; 

It's quite common for a native function to return a pointer to an array of elements. Typed pointers can be dereferenced as an array to obtain individual elements.

my $n = 5; 
 # returns a pointer to an array of length $n 
 my Pointer[Point] $plot = some_other_c_routine($n); 
 # display the 5 elements in the array 
 for 1 .. $n -> $i { 
     my $x = $plot[$i - 1].x; 
     my $y = $plot[$i - 1].y; 
     say "$i: ($x, $y)"; 

Pointers can also be updated to reference successive elements in the array:

my Pointer[Point] $elem = $plot; 
 # show differences between successive points 
 for 1 ..^ $n { 
     my Point $lo = $elem.deref; 
     ++$elem; # equivalent to $elem = $elem.add(1); 
     my Point $hi = (++$elem).deref; 
     my $dx = $hi.x = $lo.x; 
     my $dy = $hi.y = $lo.y; 
     say "$_: delta ($dx, $dy)"; 


Explicit memory management

Let's say there is some C code that caches strings passed, like so:

#include <stdlib.h> 
 static char *__VERSION; 
 char * 
     return __VERSION; 
 char * 
 set_version(char *version) 
     if (__VERSION != NULL) free(__VERSION); 
     __VERSION = version; 
     return __VERSION; 

If you were to write bindings for get_version and set_version, they would initially look like this, but will not work as intended:

sub get_version(--> Str)     is native('./version') { * } 
 sub set_version(Str --> Str) is native('./version') { * } 
 say set_version('1.0.0'); # 1.0.0 
 say get_version;          # Differs on each run 
 say set_version('1.0.1'); # Double free; segfaults 

This code segfaults on the second set_version call because it tries to free the string passed on the first call after the garbage collector had already done so. If the garbage collector shouldn't free a string passed to a native function, use explicitly-manage with it:

say set_version(explicitly-manage('1.0.0')); # 1.0.0 
 say get_version;                             # 1.0.0 
 say set_version(explicitly-manage('1.0.1')); # 1.0.1 
 say get_version;                             # 1.0.1 

Bear in mind all memory management for explicitly managed strings must be handled by the C library itself or through the NativeCall API to prevent memory leaks.

Buffers and blobs



Function arguments

NativeCall also supports native functions that take functions as arguments. One example of this is using function pointers as callbacks in an event-driven system. When binding these functions via NativeCall, one need only provide the equivalent signature as a constraint on the code parameter:

use NativeCall;
# void SetCallback(int (*callback)(const char *))
my sub SetCallback(&callback (Str --> int32)) is native('mylib') { * }

Note: the native code is responsible for memory management of values passed to Perl 6 callbacks this way. In other words, NativeCall will not free() strings passed to callbacks.

Library Paths and Names


TBD more

The native trait accepts the library name or the full path.

use NativeCall;
constant LIBMYSQL = 'mysqlclient';
constant LIBFOO = '/usr/lib/';
# and later
sub mysql_affected_rows returns int32 is native(LIBMYSQL) {*};
sub bar is native(LIBFOO) {*}

You can also put an incomplete path like './foo' and NativeCall will automatically put the right extension according to the platform specification.

BE CAREFUL: the native trait and constant are evaluated at compile time. Don't write a constant that depends on a dynamic variable like:

constant LIBMYSQL = %*ENV<P6LIB_MYSQLCLIENT> || 'mysqlclient';

This will keep the value given at compile time. A module will be precompiled and LIBMYSQL will keep the value it acquires when the module gets precompiled.

ABI/API Version

If you write native('foo') NativeCall will search under Unix like system (libfoo.dynlib on OS X, foo.dll on win32). In most modern system it will require you or the user of your module to install the development package because it's recommended to always provide an API/ABI version to a shared library, so ends often being a symbolic link provided only by a development package.

To avoid that, the native trait allows you to specify the API/ABI version. It can be a full version or just a part of it. (Try to stick to Major version, some BSD code does not care for Minor.)

use NativeCall;
sub foo1 is native('foo', v1) {*} # Will try to load
sub foo2 is native('foo', v1.2.3) {*} # Will try to load

my List $lib = ('foo', 'v1');
sub foo3 is native($lib) {*}


The native trait also accepts a Callable as argument, allowing you to provide your own way to handle the way it will find the library file to load.

use NativeCall;
sub foo is native(sub {''}) {*}

It will only be called at the first invocation of the sub.

Calling into the standard library

If you want to call a C function that's already loaded, either from the standard library or from your own program, you can omit the value, so is native.

For example on a UNIX-like operating system, you could use the following code to print the home directory of the current user:

use NativeCall;
my class PwStruct is repr('CStruct') {
    has Str $.pw_name;
    has Str $.pw_passwd;
    has uint32 $.pw_uid;
    has uint32 $.pw_gid;
    has Str $.pw_gecos;
    has Str $.pw_dir;
    has Str $.pw_shell;
sub getuid()              returns uint32   is native { * };
sub getpwuid(uint32 $uid) returns PwStruct is native { * };

say getpwuid(getuid()).pw_dir;

Though of course $*HOME is a much easier way :-)

Exported variables

Variables exported by a library – also named "global" or "extern" variables – can be accessed using cglobal. For example:

my $var := cglobal('', 'errno', int32) 

This code binds to $var a new Proxy object that redirects all its accesses to the integer variable named "errno" as exported by the "" library.

C++ Support

NativeCall offers support to use classes and methods from C++ as shown in (and its associated C++ file). Note that at the moment it's not as tested and developed as C support.

Helper Functions

The NativeCall library exports several subroutines to help you work with data from native libraries.

sub nativecast

sub nativecast($target-type, $source) is export(:DEFAULT)

This will cast the Pointer $source to an object of $target-type. The source pointer will typically have been obtained from a call to a native subroutine that returns a pointer or as a member of a struct, this may be specified as void * in the C library definition for instance, but you may also cast from a pointer to a less specific type to a more specific one.

As a special case, if a Signature is supplied as $target-type then a subroutine will be returned which will call the native function pointed to by $source in the same way as a subroutine declared with the native trait. This is described in Function Pointers.

sub cglobal

sub cglobal($libname, $symbol, $target-type) is export is rw

This returns a Proxy object that provides access to the extern named $symbol that is exposed by the specified library. The library can be specified in the same ways that they can be to the native trait.

sub nativesizeof

sub nativesizeof($obj) is export(:DEFAULT)

This returns the size in bytes of the supplied object, it can be thought of as being equivalent to sizeof in C. The object can be a builtin native type such as int64 or num64, a CArray or a class with the repr CStruct, CUnion or CPointer.

sub explicitly-manage

sub explicitly-manage($str) is export(:DEFAULT)

This returns a CStr object for the given Str. If the string returned is passed to a NativeCall subroutine, it will not be freed by the runtime's garbage collector.


Some specific examples, and instructions to use examples above in particular platforms.


The PostgreSQL examples in DBIish make use of the NativeCall library and is native to use the native _putenv function call in Windows.


NOTE: Please bear in mind that, under the hood, Debian has substituted MySQL with MariaDB since the Stretch version, so if you want to install MySQL, use MySQL APT repository instead of the default repository.

To use the MySQL example in DBIish, you'll need to install MySQL server locally; on Debian-esque systems it can be installed with something like:

 sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb # Don't forget to select 5.6.x 
 sudo apt-get update 
 sudo apt-get install mysql-community-server -y 
 sudo apt-get install libmysqlclient18 -y 

Prepare your system along these lines before trying out the examples:

$ mysql -u root -p 

Microsoft Windows

Here is an example of a Windows API call:

use NativeCall; 
 sub MessageBoxA(int32, Str, Str, int32) 
     returns int32 
     is native('user32') 
     { * } 
 MessageBoxA(0, "We have NativeCall", "ohai", 64); 

Short Tutorial on calling a C function

This is an example for calling a standard function and using the returned information in a Perl 6 program.

getaddrinfo is a POSIX standard function for obtaining network information about a network node, e.g., It is an interesting function to look at because it illustrates a number of the elements of NativeCall.

The Linux manual provides the following information about the C callable function:

int getaddrinfo(const char *node, const char *service, 
        const struct addrinfo *hints, 
        struct addrinfo **res); 

The function returns a response code 0 = error, 1 = success. The data are extracted from a linked list of addrinfo elements, with the first element pointed to by res.

From the table of NativeCall Types we know that an int is int32. We also know that a char * is one of the forms C for a C Str, which maps simply to Str. But addrinfo is a structure, which means we will need to write our own Type class. However, the function declaration is straightforward:

sub getaddrinfo( Str $node, Str $service, Addrinfo $hints, Pointer $res is rw ) 
     returns int32 
     is native 
     { * } 

Note that $res is to be written by the function, so it must be labeled as rw. Since the library is standard POSIX, the library name can be the Type definition or null.

We now have to handle structure Addrinfo. The Linux Manual provides this information:

struct addrinfo { 
                int              ai_flags; 
                int              ai_family; 
                int              ai_socktype; 
                int              ai_protocol; 
                socklen_t        ai_addrlen; 
                struct sockaddr *ai_addr; 
                char            *ai_canonname; 
                struct addrinfo *ai_next; 

The int, char* parts are straightforward. Some research indicates that socklen_t can be architecture dependent, but is an unsigned integer of at least 32 bits. So socklen_t can be mapped to the uint32 type.

The complication is sockaddr which differs depending on whether ai_socktype is undefined, INET, or INET6 (a standard v4 IP address or a v6 address).

So we create a Perl 6 class to map to the C struct addrinfo; while we're at it, we also create another class for SockAddr which is needed for it.

class SockAddr is repr('CStruct') { 
     has int32    $.sa_family; 
     has Str      $.sa_data; 
 class Addrinfo is repr('CStruct') { 
     has int32     $.ai_flags; 
     has int32     $.ai_family; 
     has int32     $.ai_socktype; 
     has int32     $.ai_protocol; 
     has int32     $.ai_addrlen; 
     has SockAddr  $.ai_addr       is rw; 
     has Str       $.ai_cannonname is rw; 
     has Addrinfo  $.ai_next       is rw; 

The is rw on the last three attributes reflects that these were defined in C to be pointers.

The important thing here for mapping to a C Struct is the structure of the state part of the class, that is the attributes. However, a class can have methods and NativeCall does not 'touch' them for mapping to C. This means that we can add extra methods to the class to unpack the attributes in a more readable manner, e.g.,

method flags { 
     do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 

By defining an appropriate enum, flags will return a string of keys rather than a bit packed integer.

The most useful information in the sockaddr structure is the address of node, which depends on the family of the Socket. So we can add method address to the Perl 6 class that interprets the address depending on the family.

In order to get a human readable IP address, there is the C funtion inet_ntop which returns a char * given a buffer with the addrinfo.

Putting all these together, leads to the following program:

#!/usr/bin/env perl6 
 use v6; 
 use NativeCall; 
 constant \INET_ADDRSTRLEN = 16; 
 constant \INET6_ADDRSTRLEN = 46; 
 enum AddrInfo-Family ( 
     AF_UNSPEC                   => 0; 
     AF_INET                     => 2; 
     AF_INET6                    => 10; 
 enum AddrInfo-Socktype ( 
     SOCK_STREAM                 => 1; 
     SOCK_DGRAM                  => 2; 
     SOCK_RAW                    => 3; 
     SOCK_RDM                    => 4; 
     SOCK_SEQPACKET              => 5; 
     SOCK_DCCP                   => 6; 
     SOCK_PACKET                 => 10; 
 enum AddrInfo-Flags ( 
     AI_PASSIVE                  => 0x0001; 
     AI_CANONNAME                => 0x0002; 
     AI_NUMERICHOST              => 0x0004; 
     AI_V4MAPPED                 => 0x0008; 
     AI_ALL                      => 0x0010; 
     AI_ADDRCONFIG               => 0x0020; 
     AI_IDN                      => 0x0040; 
     AI_CANONIDN                 => 0x0080; 
     AI_IDN_ALLOW_UNASSIGNED     => 0x0100; 
     AI_IDN_USE_STD3_ASCII_RULES => 0x0200; 
     AI_NUMERICSERV              => 0x0400; 
 sub inet_ntop(int32, Pointer, Blob, int32 --> Str) 
     is native {} 
 class SockAddr is repr('CStruct') { 
     has uint16 $.sa_family; 
 class SockAddr-in is repr('CStruct') { 
     has int16 $.sin_family; 
     has uint16 $.sin_port; 
     has uint32 $.sin_addr; 
     method address { 
         my $buf = buf8.allocate(INET_ADDRSTRLEN); 
             $buf, INET_ADDRSTRLEN) 
 class SockAddr-in6 is repr('CStruct') { 
     has uint16 $.sin6_family; 
     has uint16 $.sin6_port; 
     has uint32 $.sin6_flowinfo; 
     has uint64 $.sin6_addr0; 
     has uint64 $.sin6_addr1; 
     has uint32 $.sin6_scope_id; 
     method address { 
         my $buf = buf8.allocate(INET6_ADDRSTRLEN); 
             $buf, INET6_ADDRSTRLEN) 
 class Addrinfo is repr('CStruct') { 
     has int32 $.ai_flags; 
     has int32 $.ai_family; 
     has int32 $.ai_socktype; 
     has int32 $.ai_protocol; 
     has uint32 $.ai_addrNativeCalllen; 
     has SockAddr $.ai_addr is rw; 
     has Str $.ai_cannonname is rw; 
     has Addrinfo $.ai_next is rw; 
     method flags { 
         do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 
     method family { 
     method socktype { 
     method address { 
         given $.family { 
             when AF_INET { 
                 nativecast(SockAddr-in, $!ai_addr).address 
             when AF_INET6 { 
                 nativecast(SockAddr-in6, $!ai_addr).address 
 sub getaddrinfo(Str $node, Str $service, Addrinfo $hints, 
                 Pointer $res is rw --> int32) 
     is native {}; 
 sub freeaddrinfo(Pointer) 
     is native {} 
 sub MAIN() { 
     my Addrinfo $hint .= new(:ai_flags(AI_CANONNAME)); 
     my Pointer $res .= new; 
     my $rv = getaddrinfo("", Str, $hint, $res); 
     say "return val: $rv"; 
     if ( ! $rv ) { 
         my $addr = nativecast(Addrinfo, $res); 
         while $addr { 
             with $addr { 
                 say "Name: ", $_ with .ai_cannonname; 
                 say .family, ' ', .socktype; 
                 say .address; 
                 $addr = .ai_next; 

This produces the following output:

return val: 0 

32 Object Orientation

Object Orientation in Perl 6

Perl 6 provides strong support for Object Oriented Programming (OOP). Although Perl 6 allows programmers to program in multiple paradigms, Object Oriented Programming is at the heart of the language.

Perl 6 comes with a wealth of predefined types, which can be classified in two categories: normal and native types. Everything that you can store in a variable is either a native value or an object. That includes literals, types (type objects), code and containers.

Native types are used for low-level types (like uint64). Even if native types do not have the same capabilities as objects, if you call methods on them, they are automatically boxed into normal objects.

Everything that is not a native value is an <object>. Objects do allow for both inheritance and encapsulation.

Using Objects

To call a method on an object, add a dot, followed by the method name:

say "abc".uc; 
 # OUTPUT: «ABC␤» 

This calls the uc method on "abc", which is an object of type Str. To supply arguments to the method, add arguments inside parentheses after the method.

my $formatted-text = "Fourscore and seven years ago...".indent(8); 
 say $formatted-text; 
 # OUTPUT: «        Fourscore and seven years ago...␤» 

$formatted-text now contains the above text, but indented 8 spaces.

Multiple arguments are separated by commas:

my @words = "Abe", "Lincoln"; 
 @words.push("said", $formatted-text.comb(/\w+/)); 
 say @words; 
 # OUTPUT: «[Abe Lincoln said (Fourscore and seven years ago)]␤» 

Multiple arguments can be specified by separating the argument list with a colon:

say @words.join: '--'; 
 # OUTPUT: «Abe--Lincoln--said--Fourscore--and--seven--years--ago␤» 

Since you have to put a : after the method if you want to pass arguments without parentheses, a method call without a colon or parentheses is unambiguously a method call without an argument list:

say 4.log:   ; # OUTPUT: «1.38629436111989␤» ( natural logarithm of 4 )
say 4.log: +2; # OUTPUT: «2␤» ( base-2 logarithm of 4 )
say 4.log  +2; # OUTPUT: «3.38629436111989␤» ( natural logarithm of 4, plus 2 )

Many operations that don't look like method calls (for example, smart matching, or interpolating an object into a string) result in method calls under the hood.

Methods can return mutable containers, in which case you can assign to the return value of a method call. This is how read-writable attributes to objects are used:

$* = "\r\n"; 

Here, we call method nl-in on the $*IN object, without arguments, and assign to the container it returned with the = operator.

All objects support methods from class Mu, which is the type hierarchy root. All objects derive from Mu.

Type Objects

Types themselves are objects and you can get the type object by writing its name:

my $int-type-obj = Int; 

You can ask any object for its type object by calling the WHAT method (which is actually a macro in method form):

my $int-type-obj = 1.WHAT; 

Type objects (other than Mu) can be compared for equality with the === identity operator:

sub f(Int $x) { 
     if $x.WHAT === Int { 
         say 'you passed an Int'; 
     else { 
         say 'you passed a subtype of Int'; 

Although, in most cases, the .isa method will suffice:

sub f($x) { 
     if $x.isa(Int) { 

Subtype checking is done by smart-matching:

if $type ~~ Real { 
     say '$type contains Real or a subtype thereof'; 


Classes are declared using the class keyword, typically followed by a name.

class Journey { }

This declaration results in a type object being created and installed in the current package and current lexical scope under the name Journey. You can also declare classes lexically:

my class Journey { }

This restricts their visibility to the current lexical scope, which can be useful if the class is an implementation detail nested inside a module or another class.


Attributes are variables that exist per instance of a class; when instantiated to a value, the association between the variable and its value is called a property. They are where the state of an object is stored. In Perl 6, all attributes are private, that means they can be accessed directly only by the class instance itself. They are typically declared using the has declarator and the ! twigil.

class Journey {
    has $!origin;
    has $!destination;
    has @!travelers;
    has $!notes;

While there is no such thing as a public (or even protected) attribute, there is a way to have accessor methods generated automatically: replace the ! twigil with the . twigil (the . should remind you of a method call).

class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes;

This defaults to providing a read-only accessor. In order to allow changes to the attribute, add the is rw trait:

class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes is rw;

Now, after a Journey object is created, its .origin, .destination, and .notes will all be accessible from outside the class, but only .notes can be modified.

If an object is instantiated without certain attributes, such as origin or destination, we may not get the desired result. To prevent this, provide default values or make sure that an attribute is set on object creation by marking an attribute with an is required trait.

class Journey {
    # error if origin is not provided
    has $.origin is required;
    # set the destination to Orlando as default (unless that is the origin!)
    has $.destination = self.origin eq 'Orlando' ?? 'Kampala' !! 'Orlando';
    has @!travelers;
    has $.notes is rw;

Since classes inherit a default constructor from Mu and we have requested that some accessor methods are generated for us, our class is already somewhat functional.

# Create a new instance of the class. 
 my $vacation = 
     origin      => 'Sweden', 
     destination => 'Switzerland', 
     notes       => 'Pack hiking gear!' 
 # Use an accessor; this outputs Sweden. 
 say $vacation.origin; 
 # Use an rw accessor to change the value. 
 $vacation.notes = 'Pack hiking gear and sunglasses!'; 

Note that, although the default constructor can initialize read-only attributes, it will only set attributes that have an accessor method. That is, even if you pass travelers => ["Alex", "Betty"] to the default constructor, the attribute @!travelers is not initialized.


Methods are declared with the method keyword inside a class body.

class Journey { 
     has $.origin; 
     has $.destination; 
     has @!travelers; 
     has $.notes is rw; 
     method add-traveler($name) { 
         if $name ne any(@!travelers) { 
             push @!travelers, $name; 
         else { 
             warn "$name is already going on the journey!"; 
     method describe() { 
         "From $!origin to $!destination" 

A method can have a signature, just like a subroutine. Attributes can be used in methods and can always be used with the ! twigil, even if they are declared with the . twigil. This is because the . twigil declares a ! twigil and generates an accessor method.

Looking at the code above, there is a subtle but important difference between using $!origin and $.origin in the method describe. $!origin is an inexpensive and obvious lookup of the attribute. $.origin is a method call and thus may be overridden in a subclass. Only use $.origin if you want to allow overriding.

Unlike subroutines, additional named arguments will not produce compile time or runtime errors. That allows chaining of methods via Re-dispatching.

You may write your own accessors to override any or all of the autogenerated ones.

my $ⲧ = " " xx 4;
class Journey {
    has $.origin;
    has $.destination;
    has Str $.notes is rw;

    multi method notes() { "$!notes\n" };
    multi method notes( Str $note ) { $!notes ~= "$note\n$ⲧ" };

    method Str { "⤷ $!origin\n$ⲧ" ~ self.notes() ~ "$!destination ⤶\n" };

my $trip = :origin<Here>, :destination<There>,
                        travelers => <þor Freya> );

$trip.notes("First steps");
$trip.notes("Almost there");
print $trip;

#⤷ Here
#       First steps
#       Almost there
#There ⤶

The declared multi method notes overrides the auto-generated methods implicit in the declaration of $.notes, using a different signature for reading and writing.

Method names can be resolved at runtime with the ."" operator.

class A { has $.b };
my $name = 'b';"$name"().say;
# OUTPUT: «(Any)␤»

The syntax used to update $.notes changed in this section with respect to the previous #Attributes section. Instead of an assignment:

    $vacation.notes = 'Pack hiking gear and sunglasses!'; 

we now do a method call:

    $trip.notes("First steps"); 

Overriding the default auto-generated accessor means it is no longer available to provide a mutable container on return for an assignment. A method call is the preferred approach to adding computation and logic to the update of an attribute. Many modern languages can update an attribute by overloading assignment with a “setter” method. While Perl 6 can overload the assignment operator for this purpose with a Proxy object, overloading assignment to set attributes with complex logic is currently discouraged as weaker object oriented design.

Class and Instance Methods

A method's signature can have an invocant as its first parameter followed by a colon, which allows for the method to refer to the object it was called on.

class Foo {
    method greet($me: $person) {
        say "Hi, I am $me.^name(), nice to meet you, $person";
}"Bob");    # OUTPUT: «Hi, I am Foo, nice to meet you, Bob␤»

Providing an invocant in the method signature also allows for defining the method as either as a class method, or as an object method, through the use of type constraints. The ::?CLASS variable can be used to provide the class name at compile time, combined with either :U (for class methods) or :D (for instance methods).

class Pizza {
    has $!radius = 42;
    has @.ingredients;

    # class method: construct from a list of ingredients
    method from-ingredients(::?CLASS:U $pizza: @ingredients) {
        $ ingredients => @ingredients );

    # instance method
    method get-radius(::?CLASS:D:) { $!radius }
my $p = Pizza.from-ingredients: <cheese pepperoni vegetables>;
say $p.ingredients;     # OUTPUT: «[cheese pepperoni vegetables]␤»
say $p.get-radius;      # OUTPUT: «42␤»
say Pizza.get-radius;   # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'get-radius' must be
#          an object instance of type 'Pizza',
#          not a type object of type 'Pizza'.
#          Did you forget a '.new'?»

A method can be both a class and object method by using the multi declarator:

class C {
    multi method f(::?CLASS:U:) { say "class method"  }
    multi method f(::?CLASS:D:) { say "object method" }
C.f;       # OUTPUT: «class method␤»;   # OUTPUT: «object method␤»


Inside a method, the term self is available, which is bound to the invocant. self can be used to call further methods on the invocant, including constructors:

class Box {
  has $.data;

  method make-new-box-from() { data => $!data;

self can be used in class or instance methods as well, though beware of trying to invoke one type of method from the other:

class C {
    method g()            { 42     }
    method f(::?CLASS:U:) { self.g }
    method d(::?CLASS:D:) { self.f }
C.f;        # OUTPUT: «42␤»;    # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'f' must be a type object of type 'C',
#          not an object instance of type 'C'.  Did you forget a 'multi'?»

Within methods, $.origin works the same as self.origin, however the colon-syntax for method arguments is only supported for method calls using self, not the shortcut.

Note that if the relevant methods bless, CREATE of Mu are not overloaded, self will point to the type object in those methods.

On the other hand, BUILDALL and the submethods BUILD and TWEAK are called on instances, in different stages of initialization. In the latter two submethods, submethods of the same name from subclasses have not yet run, so you should not rely on potentially virtual method calls inside these methods.

Private Methods

Methods with an exclamation mark ! before the method name are not callable from anywhere outside the defining class; such methods are private in the sense that they are not visible from outside the class that declares them. Private methods are invoked with an exclamation mark instead of a dot:

method !do-something-private($x) {
method public($x) {
    if self.precondition {
        self!do-something-private(2 * $x)

Private methods are not inherited by subclasses.


Submethods are public methods that are not inherited by subclasses. The name stems from the fact that they are semantically similar to subroutines.

Submethods are useful for object construction and destruction tasks, as well as for tasks that are so specific to a certain type that subtypes must certainly override them.

For example, the default method new calls submethod BUILD on each class in an inheritance chain:

class Point2D { 
     has $.x; 
     has $.y; 
     submethod BUILD(:$!x, :$!y) { 
         say "Initializing Point2D"; 
 class InvertiblePoint2D is Point2D { 
     submethod BUILD() { 
         say "Initializing InvertiblePoint2D"; 
     method invert {  => - $.x, y => - $.y); 
 say => 1, y => 2); 
 # OUTPUT: «Initializing Point2D␤» 
 # OUTPUT: «Initializing InvertiblePoint2D␤» 
 # OUTPUT: « => 1, y => 2)␤» 

See also: #Object Construction.


Classes can have parent classes.

class Child is Parent1 is Parent2 { } 

If a method is called on the child class, and the child class does not provide that method, the method of that name in one of the parent classes is invoked instead, if it exists. The order in which parent classes are consulted is called the method resolution order (MRO). Perl 6 uses the C3 method resolution order. You can ask a type for its MRO through a call to its meta class:

say List.^mro;      # ((List) (Cool) (Any) (Mu))

If a class does not specify a parent class, Any is assumed by default. All classes directly or indirectly derive from Mu, the root of the type hierarchy.

All calls to public methods are "virtual" in the C++ sense, which means that the actual type of an object determines which method to call, not the declared type:

class Parent { 
     method frob { 
         say "the parent class frobs" 
 class Child is Parent { 
     method frob { 
         say "the child's somewhat more fancy frob is called" 
 my Parent $test; 
 $test =; 
 $test.frob;          # calls the frob method of Child rather than Parent 
 # OUTPUT: «the child's somewhat more fancy frob is called␤» 

Object Construction

Objects are generally created through method calls, either on the type object or on another object of the same type.

Class Mu provides a constructor method called new, which takes named arguments and uses them to initialize public attributes.

class Point {
    has $.x;
    has $.y;
my $p = x => 5, y => 2);
#             ^^^ inherited from class Mu
say "x: ", $p.x;
say "y: ", $p.y;
# OUTPUT: «x: 5␤»
# OUTPUT: «y: 2␤» calls method bless on its invocant, passing all the named arguments. bless creates the new object and then calls method BUILDALL on it. BUILDALL walks all subclasses in reverse method resolution order (i.e. from Mu to most derived classes) and in each class checks for the existence of a method named BUILD. If the method exists, the method is called with all the named arguments from the new method. If not, the public attributes from this class are initialized from named arguments of the same name. In either case, if neither BUILD nor the default mechanism has initialized the attribute, default values are applied.

After the BUILD methods have been called, methods named TWEAK are called, if they exist, again with all the named arguments that were passed to new. See an example of its use below.

Due to the default behavior of BUILDALL and BUILD submethods, named arguments to the constructor new derived from Mu can correspond directly to public attributes of any of the classes in the method resolution order, or to any named parameter of any BUILD submethod.

This object construction scheme has several implications for customized constructors. First, custom BUILD methods should always be submethods, otherwise they break attribute initialization in subclasses. Second, BUILD submethods can be used to run custom code at object construction time. They can also be used for creating aliases for attribute initialization:

class EncodedBuffer { 
     has $.enc; 
     has $.data; 
     submethod BUILD(:encoding(:$enc), :$data) { 
         $!enc  :=  $enc; 
         $!data := $data; 
 my $b1 = encoding => 'UTF-8', data => [64, 65] ); 
 my $b2 = enc      => 'UTF-8', data => [64, 65] ); 
 #  both enc and encoding are allowed now 

Since passing arguments to a routine binds the arguments to the parameters, a separate binding step is unnecessary if the attribute is used as a parameter. Hence the example above could also have been written as:

submethod BUILD(:encoding(:$!enc), :$!data) { 
     # nothing to do here anymore, the signature binding 
     # does all the work for us. 

However, be careful when using this auto-binding of attributes when the attribute may have special type requirements, such as an :$!id that must be a positive integer. Remember, default values will be assigned unless you specifically take care of this attribute, and that default value will be Any, which would cause a type error.

The third implication is that if you want a constructor that accepts positional arguments, you must write your own new method:

class Point {
    has $.x;
    has $.y;
    method new($x, $y) {
        self.bless(:$x, :$y);

However this is considered poor practice, because it makes correct initialization of objects from subclasses harder.

Another thing to note is that the name new is not special in Perl 6. It is merely a common convention. You can call bless from any method at all, or use CREATE to fiddle around with low-level workings.

Another pattern of hooking into object construction is by writing your own method BUILDALL. To make sure that initialization of superclasses works fine, you need to callsame to invoke the parent classes BUILDALL.

class MyClass { 
     method BUILDALL(|) { 
         # initial things here 
         callsame;   # call the parent classes (or default) BUILDALL 
         # you can do final checks here. 
         self # return the fully built object 

The TWEAK method allows you to check things or modify attributes after object construction:

class RectangleWithCachedArea { 
     has ($.x1, $.x2, $.y1, $.y2); 
     has $.area; 
     submethod TWEAK() { 
         $!area = abs( ($!x2 - $!x1) * ( $!y2 - $!y1) ); 
 say x2 => 5, x1 => 1, y2 => 1, y1 => 0).area; 
 # OUTPUT: «4␤» 

Object Cloning

The cloning is done using clone method available on all objects, which shallow-clones both public and private attributes. New values for public attributes can be supplied as named arguments.

class Foo { 
     has $.foo = 42; 
     has $.bar = 100; 
 my $o1 =; 
 my $o2 = $o1.clone: :bar(5000); 
 say $o1; # => 42, bar => 100) 
 say $o2; # => 42, bar => 5000) 

See document for clone for details on how non-scalar attributes get cloned, as well as examples of implementing your own custom clone methods.


Roles are in some ways similar to classes, in that they are a collection of attributes and methods. They differ in that roles are also meant for describing only parts of an object's behavior and in how roles are applied to classes. Or to phrase it differently, classes are meant for managing objects and roles are meant for managing behavior and code reuse.

 role Serializable { 
     method serialize() { 
         self.perl; # very primitive serialization 
     method deserialize($buf) { 
         EVAL $buf; # reverse operation to .perl 
 class Point does Serializable { 
     has $.x; 
     has $.y; 
 my $p =, :y(2)); 
 my $serialized = $p.serialize; 
 my $clone-of-p = Point.deserialize($serialized); 
 say $clone-of-p.x; # OUTPUT: «1␤» 

Roles are immutable as soon as the compiler parses the closing curly brace of the role declaration.

Application of Role

Role application differs significantly from class inheritance. When a role is applied to a class, the methods of that role are copied into the class. If multiple roles are applied to the same class, conflicts (e.g. attributes or non-multi methods of the same name) cause a compile-time error, which can be solved by providing a method of the same name in the class.

This is much safer than multiple inheritance, where conflicts are never detected by the compiler, but are instead resolved to the superclass that appears earlier in the method resolution order, which might not be what the programmer wanted.

For example, if you've discovered an efficient method to ride cows, and are trying to market it as a new form of popular transportation, you might have a class Bull, for all the bulls you keep around the house, and a class Automobile, for things that you can drive.

class Bull {
    has Bool $.castrated = False;
    method steer {
        # Turn your bull into a steer
        $!castrated = True;
        return self;
class Automobile {
    has $.direction;
    method steer($!direction) { }
class Taurus is Bull is Automobile { }

my $t =;
say $t.steer;
# OUTPUT: « => Bool::True, direction => Any)␤»

With this setup, your poor customers will find themselves unable to turn their Taurus and you won't be able to make more of your product! In this case, it may have been better to use roles:

role Bull-Like { 
     has Bool $.castrated = False; 
     method steer { 
         # Turn your bull into a steer 
         $!castrated = True; 
         return self; 
 role Steerable { 
     has Real $.direction; 
     method steer(Real $d = 0) { 
         $!direction += $d; 
 class Taurus does Bull-Like does Steerable { } 

This code will die with something like:

 Method 'steer' must be resolved by class Taurus because it exists in 
 multiple roles (Steerable, Bull-Like) 

This check will save you a lot of headaches:

class Taurus does Bull-Like does Steerable { 
     method steer($direction?) { 

When a role is applied to a second role, the actual application is delayed until the second role is applied to a class, at which point both roles are applied to the class. Thus

role R1 {
    # methods here
role R2 does R1 {
    # methods here
class C does R2 { }

produces the same class C as

role R1 {
    # methods here
role R2 {
    # methods here
class C does R1 does R2 { }


When a role contains a stubbed method, a non-stubbed version of a method of the same name must be supplied at the time the role is applied to a class. This allows you to create roles that act as abstract interfaces.

role AbstractSerializable { 
     method serialize() { ... }        # literal ... here marks the 
                                       # method as a stub 
 # the following is a compile time error, for example 
 #        Method 'serialize' must be implemented by Point because 
 #        it's required by a role 
 class APoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
 # this works: 
 class SPoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
     method serialize() { "p($.x, $.y)" } 

The implementation of the stubbed method may also be provided by another role.


Roles cannot inherit from classes, but they may carry classes, causing any class which does that role to inherit from the carried classes. So if you write:

role A is Exception { } 
 class X::Ouch does A { } 
 X::Ouch.^parents.say # OUTPUT: «((Exception))␤» 

then X::Ouch will inherit directly from Exception, as we can see above by listing its parents.

As they do not use what can properly be called inheritance, roles are not part of the class hierarchy. Roles are listed with the .^roles meta-method instead, which uses transitive as flag for including all levels or just the first one. Despite this, a class or instance may still be tested with smartmatches or type constraints to see if it does a role.

role F { } 
 class G does F { } 
 G.^roles.say;                    # OUTPUT: «((F))␤» 
 role Ur {} 
 role Ar does Ur {} 
 class Whim does Ar {}; Whim.^roles(:!transitive).say;   # OUTPUT: «((Ar))␤» 
 say G ~~ F;                      # OUTPUT: «True␤» 
 multi a (F $a) { "F".say } 
 multi a ($a)   { "not F".say } 
 a(G);                            # OUTPUT: «F␤» 

Pecking order

A method defined directly in a class will always override definitions from applied roles or from inherited classes. If no such definition exists, methods from roles override methods inherited from classes. This happens both when said class was brought in by a role, and also when said class was inherited directly.

role M {
  method f { say "I am in role M" }

class A {
  method f { say "I am in class A" }

class B is A does M {
  method f { say "I am in class B" }

class C is A does M { }; # OUTPUT «I am in class B␤»; # OUTPUT «I am in role M␤»

Note that each candidate for a multi-method is its own method. In this case, the above only applies if two such candidates have the same signature. Otherwise, there is no conflict, and the candidate is just added to the multi-method.

Automatic Role Punning

Any attempt to directly instantiate a role or use it as a type object will automatically create a class with the same name as the role, making it possible to transparently use a role as if it were a class.

role Point { 
     has $.x; 
     has $.y; 
     method abs { sqrt($.x * $.x + $.y * $.y) } 
     method dimensions { 2 } 
 say => 6, y => 8).abs; # OUTPUT «10␤» 
 say Point.dimensions;              # OUTPUT «2␤» 

We call this automatic creation of classes punning, and the generated class a pun.

Punning is not caused by most meta-programming constructs, however, as those are sometimes used to work directly with roles.

Parameterized Roles

Roles can be parameterized, by giving them a signature in square brackets:

role BinaryTree[::Type] { 
     has BinaryTree[Type] $.left; 
     has BinaryTree[Type] $.right; 
     has Type $.node; 
     method visit-preorder(&cb) { 
         cb $.node; 
         for $.left, $.right -> $branch { 
             $branch.visit-preorder(&cb) if defined $branch; 
     method visit-postorder(&cb) { 
         for $.left, $.right -> $branch { 
             $branch.visit-postorder(&cb) if defined $branch; 
         cb $.node; 
     method new-from-list(::?CLASS:U: *@el) { 
         my $middle-index = @el.elems div 2; 
         my @left         = @el[0 .. $middle-index - 1]; 
         my $middle       = @el[$middle-index]; 
         my @right        = @el[$middle-index + 1 .. *];  
             node    => $middle, 
             left    => @left  ??  !! self, 
             right   => @right ?? !! self, 
 my $t = BinaryTree[Int].new-from-list(4, 5, 6); 
 $t.visit-preorder(&say);    # OUTPUT: «5␤4␤6␤» 
 $t.visit-postorder(&say);   # OUTPUT: «4␤6␤5␤» 

Here the signature consists only of a type capture, but any signature will do:

enum Severity <debug info warn error critical>; 
 role Logging[$filehandle = $*ERR] { 
     method log(Severity $sev, $message) { 
         $filehandle.print("[{uc $sev}] $message\n"); 
 Logging[$*OUT].log(debug, 'here we go'); # OUTPUT: «[DEBUG] here we go␤» 

You can have multiple roles of the same name, but with different signatures; the normal rules of multi dispatch apply for choosing multi candidates.

Mixins of Roles

Roles can be mixed into objects. A role's given attributes and methods will be added to the methods and attributes the object already has. Multiple mixins and anonymous roles are supported.

role R { method Str() {'hidden!'} };
my $i = 2 but R;
sub f(\bound){ put bound };
f($i); # OUTPUT: «hidden!␤»

Note that the object got the role mixed in, not the object's class or the container. Thus, @-sigiled containers will require binding to make the role stick. Some operators will return a new value, which effectively strips the mixin from the result.

The operator infix:<but> is narrower than the list constructor. When providing a list of roles to mix in, always use parentheses.

role R1 { method m {} } 
 role R2 { method n {} } 
 my $a = 1 but R1,R2; # R2 is in sink context, issues a WARNING 
 say $a.^name; 
 # OUTPUT: «Int+{R1}␤» 
 my $all-roles = 1 but (R1,R2); 
 say $all-roles.^name; # OUTPUT: «Int+{R1,R2}␤» 

Mixins can be used at any point in your object's life.

# A counter for Table of Contents
role TOC-Counter {
    has Int @!counters is default(0);
    method Str() { @!counters.join: '.' }
    method inc($level) {
        @!counters[$level - 1]++;

my Num $toc-counter = NaN;     # don't do math with Not A Number
say $toc-counter;              # OUTPUT: «NaN␤»
$toc-counter does TOC-Counter; # now we mix the role in
put $toc-counter / 1;          # OUTPUT: «NaN␤» (because that's numerical context)
put $toc-counter;              # OUTPUT: «2.2.2␤» (put will call TOC-Counter::Str)

Roles can be anonymous.

my %seen of Int is default(0 but role :: { method Str() {'NULL'} });
say %seen<not-there>;          # OUTPUT: «NULL␤»
say %seen<not-there>.defined;  # OUTPUT: «True␤» (0 may be False but is well defined)
say<not-there>); # OUTPUT: «0␤»

Meta-Object Programming and Introspection

Perl 6 has a meta object system, which means that the behavior of objects, classes, roles, grammars, enums, etc. are themselves controlled by other objects; those objects are called meta objects. Meta objects are, like ordinary objects, instances of classes, in this case we call them meta classes.

For each object or class you can get the meta object by calling .HOW on it. Note that although this looks like a method call, it works more like a macro.

So, what can you do with the meta object? For one you can check if two objects have the same meta class by comparing them for equality:

say 1.HOW ===   2.HOW;      # OUTPUT: «True␤»
say 1.HOW === Int.HOW;      # OUTPUT: «True␤»
say 1.HOW === Num.HOW;      # OUTPUT: «False␤»

Perl 6 uses the word HOW, Higher Order Workings, to refer to the meta object system. Thus it should be no surprise that in Rakudo, the class name of the meta class that controls class behavior is called Perl6::Metamodel::ClassHOW. For each class there is one instance of Perl6::Metamodel::ClassHOW.

But of course the meta model does much more for you. For example, it allows you to introspect objects and classes. The calling convention for methods on meta objects is to call the method on the meta object and pass in the object of interest as first argument to the object. So to get the name of the class of an object, you could write:

my $object = 1;
my $metaobject = 1.HOW;
say $$object);      # OUTPUT: «Int␤»

# or shorter:
say;                  # OUTPUT: «Int␤»

(The motivation is that Perl 6 also wants to allow a more prototype-based object system, where it's not necessary to create a new meta object for every type).

There's a shortcut to keep from using the same object twice:

say 1.^name;                        # OUTPUT: «Int␤»
# same as
say;                  # OUTPUT: «Int␤»

See Metamodel::ClassHOW for documentation on the meta class of class and also the general documentation on the meta object protocol.

33 Operators

Common Perl 6 infixes, prefixes, postfixes, and more!

See Sub on how to define operators.

Operator Precedence

In an expression like 1 + 2 * 3, the 2 * 3 is evaluated first because the infix * has tighter precedence than the +.

The following table summarizes the precedence levels in Perl 6, from tightest to loosest:

A Level Examples
N Terms 42 3.14 "eek" qq["foo"] $x :!verbose @$array
L Method postfix .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ .:
N Autoincrement ++ --
R Exponentiation **
L Symbolic unary ! + - ~ ? | || +^ ~^ ?^ ^
L Dotty infix .= .
L Multiplicative * × / ÷ % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm
L Additive + - − +| +^ ~| ~^ ?| ?^
L Replication x xx
X Concatenation ~ o ∘
X Junctive and & (&) (.) ∩ ⊍
X Junctive or | ^ (|) (^) (+) (-) ∪ ⊖ ⊎ ∖
L Named unary temp let
N Structural infix but does <=> leg unicmp cmp coll .. ..^ ^.. ^..^
C Chaining infix != ≠ == < <= ≤ > >= ≥ eq ne lt le gt ge ~~ === eqv !eqv =~= ≅ (elem) (cont) (<) (>) (<=) (>=) (<+) (>+) ∈ ∉ ∋ ∌ ⊂ ⊄ ⊃ ⊅ ⊆ ⊈ ⊇ ⊉ ≼ ≽
X Tight and &&
X Tight or || ^^ // min max
R Conditional ?? !! ff ff^ ^ff ^ff^ fff fff^ ^fff ^fff^
R Item assignment = => += -= **= xx=
L Loose unary so not
X Comma operator , :
X List infix Z minmax X X~ X* Xeqv ... … ...^ …^
R List prefix print push say die map substr ... [+] [*] any Z=
X Loose and and andthen notandthen
X Loose or or xor orelse
X Sequencer <==, ==>, <<==, ==>>
N Terminator ; {...}, unless, extra ), ], }

Using two ! symbols below generically to represent any pair of operators that have the same precedence, the associativities specified above for binary operators are interpreted as follows:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

For unary operators this is interpreted as:

A Assoc Meaning of !$a!
L left (!$a)!
R right !($a!)

In the operator descriptions below, a default associativity of left is assumed.

Operator classification

Operators can occur in several positions relative to a term:

+term prefix
term1 + term2 infix
term++ postfix
(term) circumfix
term1[term2] postcircumfix

Each operator is also available as a subroutine. The name of the routine is formed from the operator category, followed by a colon, then a list quote construct with the symbol(s) that make up the operator:

infix:<+>(1, 2);                # same as 1 + 2
circumfix:«[ ]»(<a b c>);       # same as [<a b c>]

As a special case, a listop (list operator) can stand either as a term or as a prefix. Subroutine calls are the most common listops. Other cases include meta-reduced infix operators ([+] 1, 2, 3) and the #prefix ... etc. stub operators.

Defining custom operators is covered in Defining Operators functions.

Meta Operators

Meta operators can be parameterized with other operators or subroutines in the same way as functions can take functions as parameters. To use a subroutine as a parameter, prefix its name with a &. Perl 6 will generate the actual combined operator in the background, allowing the mechanism to be applied to user defined operators. To disambiguate chained meta operators, enclose the inner operator in square brackets. There are quite a few Meta operators with different semantics as explained, next.

Substitution Operators

Each substitution operator comes into two main forms: a lowercase one (e.g., s///) that performs in-place (i.e., destructive behaviour; and an uppercase form (e.g., S///) that provides a non-destructive behavior.

s/// in-place substitution

my $str = 'old string';
$str ~~ s/o .+ d/new/;
say $str; # OUTPUT: «new string␤»

s/// operates on the $_ topical variable, changing it in place. It uses the given Regex to find portions to replace and changes them to the provided replacement string. Sets $/ to the Match object or, if multiple matches were made, a List of Match objects. Returns $/.

It's common to use this operator with the ~~ smartmatch operator, as it aliases left-hand side to $_, which s/// uses.

Regex captures can be referenced in the replacement part; it takes the same adverbs as the .subst method, which go between the s and the opening /, separated with optional whitespace:

my $str = 'foo muCKed into the lEn';

# replace second 'o' with 'x'
$str ~~ s:2nd/o/x/;

# replace 'M' or 'L' followed by non-whitespace stuff with 'd'
# and lower-cased version of that stuff:
$str ~~ s :g :i/<[ML]> (\S+)/d{lc $0}/;

say $str; # OUTPUT: «fox ducked into the den␤»

You can also use a different delimiter:

my $str = 'foober';
$str ~~ s!foo!fox!;
$str ~~ s{b(.)r} = " d$0n";
say $str; # OUTPUT: «fox den␤»

Non-paired characters can simply replace the original slashes. Paired characters, like braces, are used only on the match portion, with the substitution given by assignment (of anything: a string, a routine call, etc.).

S/// non-destructive substitution

say S/o .+ d/new/ with 'old string';      # OUTPUT: «new string␤»
S:g/« (.)/$0.uc()/.say for <foo bar ber>; # OUTPUT: «Foo␤Bar␤Ber␤»

S/// uses the same semantics as the s/// operator, except it leaves the original string intact and returns the resultant string instead of $/ ($/ still being set to the same values as with s///).

Note: since the result is obtained as a return value, using this operator with the ~~ smartmatch operator is a mistake and will issue a warning. To execute the substitution on a variable that isn't the $_ this operator uses, alias it to $_ with given, with, or any other way. Alternatively, use the .subst method.

tr/// in-place transliteration

my $str = 'old string';
$str ~~ tr/dol/wne/;
say $str; # OUTPUT: «new string␤»

tr/// operates on the $_ topical variable and changes it in place. It behaves similar to Str.trans called with a single Pair argument, where key is the matching part (characters dol in the example above) and value is the replacement part (characters wne in the example above). Accepts the same adverbs as Str.trans. Returns the StrDistance object that measures the distance between original value and the resultant string.

my $str = 'old string';
$str ~~ tr:c:d/dol st//;
say $str; # OUTPUT: «ring␤»

TR/// non-destructive transliteration

with 'old string' {
    say TR/dol/wne/; # OUTPUT: «new string␤»

TR/// behaves the same as the tr/// operator, except that it leaves the $_ value untouched and instead returns the resultant string.

say TR:d/dol // with 'old string'; # OUTPUT: «string␤»

Assignment Operators

Infix operators can be combined with the assignment operator to modify a value and apply the result to a container in one go. Containers will be autovivified if possible. Some examples:

my $a = 32;
$a += 10;     # 42
$a -= 2;      # 40

$a = 3;
$a min= 5;    # still 3
$a min= 2;    # 2

my $s = 'a';
$s ~= 'b';    # 'ab'

This behavior is automatically extended to include custom-defined infix operators.

sub infix:<space-concat> ($a, $b) { $a ~ " " ~ $b };
my $a = 'word1';
$a space-concat= 'word2';     # RESULT: «'word1 word2'»

Although not strictly operators, methods can be used in the same fashion.

my Real $a = 1/2;
$a = 3.14;
$a .= round;      # RESULT: «3»

Negated Relational Operators

The result of a relational operator returning Bool can be negated by prefixing with !. To avoid visual confusion with the !! operator, you may not modify any operator already beginning with !.

There are shortcuts for !== and !eq, namely != and ne.

my $a = True;
say so $a != True;    # OUTPUT: «False␤»
my $i = 10;

my $release =, :12month, :24day);
my $today =;
say so $release !before $today;     # OUTPUT: «False␤»

Reversed Operators

Any infix operator may be called with its two arguments reversed by prefixing with R. Associativity of operands is reversed as well.

say 4 R/ 12;        # OUTPUT: «3␤»
say [R/] 2, 4, 16;  # OUTPUT: «2␤»

Hyper Operators

Hyper Operators include « and », with their ASCII variants << and >>. They apply a given operator enclosed (or preceded or followed, in the case of unary operators) by « and/or » to one or two lists, returning the resulting list, with the pointy part of « or » aimed at the shorter list. Single elements are turned to a list, so they can be used too. If one of the lists is shorter than the other, the operator will cycle over the shorter list until all elements of the longer list are processed.

say (1, 2, 3) »*» 2;          # OUTPUT: «(2 4 6)␤»
say (1, 2, 3, 4) »~» <a b>;   # OUTPUT: «(1a 2b 3a 4b)␤»
say (1, 2, 3) »+« (4, 5, 6);  # OUTPUT: «(5 7 9)␤»

Assignment meta operators can be hyped.

my @a = 1, 2, 3;
say @a »+=» 1;    # OUTPUT: «[2 3 4]␤»
my ($a, $b, $c);
(($a, $b), $c) «=» ((1, 2), 3);
say "$a, $c";       #  OUTPUT: «1, 3␤»

Hyper forms of unary operators have the pointy bit aimed at the operator and the blunt end at the list to be operated on.

my @wisdom = True, False, True;
say !« @wisdom;     # OUTPUT: «[False True False]␤»

my @a = 1, 2, 3;
@a»++;              # OUTPUT: «(2, 3, 4)␤»

Hyper operators are defined recursively on nested arrays.

say -« [[1, 2], 3]; # OUTPUT: «[[-1 -2] -3]␤»

Also, methods can be called in an out of order, concurrent fashion. The resulting list is in order. Note that all hyper operators are candidates for autothreading and will cause tears if the methods have side effects. The optimizer has full reign over hyper operators, which is the reason that they cannot be defined by the user.

class CarefulClass { method take-care {} }
my CarefulClass @objs;
my @results = @objs».take-care();

my @slops;        # May Contain Nuts

Hyper operators can work with hashes. The pointy direction indicates if missing keys are to be ignored in the resulting hash. The enclosed operator operates on all values that have keys in both hashes.

%foo «+» %bar; intersection of keys
%foo »+« %bar; union of keys
%outer »+» %inner; only keys of %inner that exist in %outer will occur in the result
my %outer = 1, 2, 3 Z=> <a b c>;
my %inner = 1, 2 Z=> <x z>;
say %outer «~» %inner;          # OUTPUT: «{"1" => "ax", "2" => "bz"}␤»

Hyper operators can take user defined operators as their operator argument.

sub pretty-file-site (Int $size --> Str) {
    # rounding version of infix:</>(Int, Int)
    sub infix:<r/>(Int \i1, Int \i2) {
        round(i1 / i2, 0.1)

    # we build a vector of fractions of $size and zip that with the fitting prefix
    for $size «[r/]« (2**60, 2**50, 2**40, 2**30, 2**20, 2**10)
              Z      <EB     PB     TB     GB     MB     KB> -> [\v,\suffix] {
        # starting with the biggest suffix,
        # we take the first that is 0.5 of that suffix or bigger
        return v ~ ' ' ~ suffix if v > 0.4
    # this be smaller or equal then 0.4 KB
    return $size.Str;

for 60, 50, 40, 30, 20, 10 -> $test {
    my &a = { (2 ** $test) * (1/4, 1/2, 1, 10, 100).pick * (1..10).pick };
    print pretty-file-site(a.Int) xx 2, ' ';

# OUTPUT: «10 EB 4 EB 2 PB 5 PB 0.5 PB 4 TB 300 GB 4.5 GB 50 MB 200 MB 9 KB 0.6 MB␤»

Whether hyperoperators descend into child lists depends on the nodality of the inner operator of a chain. For the hyper method call operator (».), the nodality of the target method is significant.

say (<a b>, <c d e>)».elems;        # OUTPUT: «(2 3)␤»
say (<a b>, <c d e>)».&{ .elems };  # OUTPUT: «((1 1) (1 1 1))␤»

You can chain hyper operators to destructure a List of Lists.

my $neighbors = ((-1, 0), (0, -1), (0, 1), (1, 0));
my $p = (2, 3);
say $neighbors »>>+<<» ($p, *);   # OUTPUT: «((1 3) (2 2) (2 4) (3 3))␤»

Reduction Operators

The reduction metaoperator, [ ], reduces a list with the given infix operator. It gives the same result as the reduce routine - see there for details.

# These two are equivalent:
say [+] 1, 2, 3;                # OUTPUT: «6␤»
say reduce &infix:<+>, 1, 2, 3; # OUTPUT: «6␤»

No whitespace is allowed between the brackets and the operator. To wrap a function instead of an operator, provide an additional layer of brackets:

sub plus { $^a + $^b };
say [[&plus]] 1, 2, 3;          # OUTPUT: «6␤»

The argument list is iterated without flattening. This means that you can pass a nested list to the reducing form of a list infix operator:

say [X~] (1, 2), <a b>;         # OUTPUT: «1, 2 X~ <a b>␤»

By default, only the final result of the reduction is returned. Prefix the wrapped operator with a \, to return a lazy list of all intermediate values instead. This is called a "triangular reduce". If the non-meta part contains a \ already, quote it with [] (e.g. [\[\x]]).

my @n = [\~] 1..*;
say @n[^5];         # OUTPUT: «(1 12 123 1234 12345)␤»

Cross Operators

The cross metaoperator, X, will apply a given infix operator in order of cross product to all lists, such that the rightmost operator varies most quickly.

1..3 X~ <a b> # RESULT: «<1a, 1b, 2a, 2b, 3a, 3b>␤»

Zip Operators

The zip metaoperator (which is not the same thing as Z) will apply a given infix operator to pairs taken one left, one right, from its arguments. The resulting list is returned.

my @l = <a b c> Z~ 1, 2, 3;     # RESULT: «[a1 b2 c3]␤»

If one of the operands runs out of elements prematurely, the zip operator will stop. An infinite list can be used to repeat elements. A list with a final element of * will repeat its 2nd last element indefinitely.

my @l = <a b c d> Z~ ':' xx *;  # RESULT: «<a: b: c: d:>»
   @l = <a b c d> Z~ 1, 2, *;   # RESULT: «<a1 b2 c2 d2>»

If an infix operator is not given, , (comma operator) will be used by default:

my @l = 1 Z 2;  # RESULT: «[(1 2)]»

Sequential Operators

The sequential metaoperator, S, will suppress any concurrency or reordering done by the optimizer. Most simple infix operators are supported.

say so 1 S& 2 S& 3;  # OUTPUT: «True␤»

Nesting of Meta Operators

To avoid ambiguity when chaining meta operators, use square brackets to help the compiler understand you.

my @a = 1, 2, 3;
my @b = 5, 6, 7;
@a X[+=] @b;
say @a;         # OUTPUT: «[19 20 21]␤»

Term Precedence

term < >

The quote-words construct breaks up the contents on whitespace and returns a List of the words. If a word looks like a number literal or a Pair literal, it's converted to the appropriate number.

say <a b c>[1];   # OUTPUT: «b␤»

term ( )

The grouping operator.

An empty group () creates an empty list. Parentheses around non-empty expressions simply structure the expression, but do not have additional semantics.

In an argument list, putting parenthesis around an argument prevents it from being interpreted as a named argument.

multi sub p(:$a!) { say 'named'      }
multi sub p($a)   { say 'positional' }
p a => 1;           # OUTPUT: «named␤»
p (a => 1);         # OUTPUT: «positional␤»

term { }

Block or Hash constructor.

If the content is empty, or contains a single list that starts with a Pair literal or %-sigiled variable, and the $_ variable or placeholder parameters are not used, the constructor returns a Hash. Otherwise it constructs a Block.

To force construction of a Block, follow the opening brace with a semicolon. To always ensure you end up with a Hash, you can use %( ) coercer or hash routine instead:

{}.^name.say;        # OUTPUT: «Hash␤»
{;}.^name.say;       # OUTPUT: «Block␤»

{:$_}.^name.say;     # OUTPUT: «Block␤»
%(:$_).^name.say;    # OUTPUT: «Hash␤»
hash(:$_).^name.say; # OUTPUT: «Hash␤»

circumfix [ ]

The Array constructor returns an itemized Array that does not flatten in list context.

Method Postfix Precedence

postcircumfix [ ]

sub postcircumfix:<[ ]>(@container, **@index, 
                         :$k, :$v, :$kv, :$p, :$exists, :$delete) 

Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".

my @alphabet = 'a' .. 'z';
say @alphabet[0];                   # OUTPUT: «a␤»
say @alphabet[1];                   # OUTPUT: «b␤»
say @alphabet[*-1];                 # OUTPUT: «z␤»
say @alphabet[100]:exists;          # OUTPUT: «False␤»
say @alphabet[15, 4, 17, 11].join;  # OUTPUT: «perl␤»
say @alphabet[23 .. *].perl;        # OUTPUT: «("x", "y", "z")␤»

@alphabet[1, 2] = "B", "C";
say @alphabet[0..3].perl            # OUTPUT: «("a", "B", "C", "d")␤»

See Subscripts, for a more detailed explanation of this operator's behavior and for how to implement support for it in custom types.

postcircumfix { }

sub postcircumfix:<{ }>(%container, **@key, 
                         :$k, :$v, :$kv, :$p, :$exists, :$delete) 

Universal interface for associative access to zero or more elements of a %container, a.k.a. "hash indexing operator".

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color{"banana"};                 # OUTPUT: «yellow␤»
say %color{"cherry", "kiwi"}.perl;    # OUTPUT: «("red", "green")␤»
say %color{"strawberry"}:exists;      # OUTPUT: «False␤»

%color{"banana", "lime"} = "yellowish", "green";
say %color;             # OUTPUT: «banana => yellowish, kiwi => green, lime => green␤»

See postcircumfix < > and postcircumfix « » for convenient shortcuts, and Subscripts for a more detailed explanation of this operator's behavior and how to implement support for it in custom types.

postcircumfix < >

Shortcut for postcircumfix { } that quotes its argument using the same rules as the quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color<banana>;               # OUTPUT: «yellow␤»
say %color<cherry kiwi>.perl;     # OUTPUT: «("red", "green")␤»
say %color<strawberry>:exists;    # OUTPUT: «False␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix « »

Shortcut for postcircumfix { } that quotes its argument using the same rules as the interpolating quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
my $fruit = "kiwi";
say %color«cherry "$fruit"».perl;   # OUTPUT: «("red", "green")␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix ( )

The call operator treats the invocant as a Callable and invokes it, using the expression between the parentheses as arguments.

Note that an identifier followed by a pair of parentheses is always parsed as a subroutine call.

If you want your objects to respond to the call operator, implement a method CALL-ME.

postfix .

The operator for calling one method, $invocant.method.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .&

The operator to call a subroutine (with at least one positional argument), such as a method. The invocant will be bound to the first positional argument.

Technically, not a real operator; it's syntax special-cased in the compiler.

my sub f($invocant){ "The arg has a value of $invocant" }
# OUTPUT: «The arg has a value of 42␤»

42.&(-> $invocant { "The arg has a value of $invocant" });
# OUTPUT: «The arg has a value of 42␤»

postfix .=

A mutating method call. $invocant.=method desugars to $invocant = $invocant.method, similar to =.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .^

A meta-method call. $invocant.^method calls method on $invocant's metaclass. It desugars to $invocant.HOW.method($invocant, ...). See HOW for more information.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .?

Safe call operator. $invocant.?method calls method method on $invocant if it has a method of such name. Otherwise it returns Nil.

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .+

$foo.+meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, it throws a X::Method::NotFound exception.

class A {
  method foo { say "from A"; }
class B is A {
  multi method foo { say "from B"; }
  multi method foo(Str) { say "from B (Str)"; }
class C is B is A {
  multi method foo { say "from C"; }
  multi method foo(Str) { say "from C (Str)"; }

say C.+foo; # OUTPUT: «from C␤from B␤from A␤(True True True)␤»

postfix .*

$foo.*meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, an empty List is returned.

Technically, postfix .+ calls .* at first. Read postfix .+ section to see examples.

postfix ». / postfix >>.

Hyper method call operator. Will call a method on all elements of a List out of order and return the list of return values in order.

my @a = <a b c>;
my @b = @a».ord;                  # OUTPUT: «[97, 98, 99]␤»
sub foo(Str:D $c){ $c.ord * 2 };  # The first parameter of a method is the invocant.
say @a».&foo;                     # So we can pretend to have a method call with a sub that got a good first positional argument.
say @a».&{ .ord};                 # Blocks have an implicit positional arguments that lands in $_. The latter can be omitted for method calls.

Take care to avoid a common mistake of expecting side-effects to occur in order. The following say is not guaranteed to produce the output in order:

@a».say;  # WRONG! Could produce a␤b␤c␤ or c␤b␤a␤ or any other order 

postfix .postfix / .postcircumfix

In most cases, a dot may be placed before a postfix or postcircumfix:

my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same

This can be useful for visual clarity or brevity. For example, if an object's attribute is a function, putting a pair of parentheses after the attribute name will become part of the method call. So, either two pairs of parentheses must be used or a dot has to come before the parentheses to separate it from the method call.

class Operation {
    has $.symbol;
    has &.function;
my $addition =<+>, :function{ $^a + $^b });
say $addition.function()(1, 2);   # OUTPUT: «3␤»
# OR
say $addition.function.(1, 2);    # OUTPUT: «3␤»

If the postfix is an identifier, however, it will be interpreted as a normal method call.

1.i # No such method 'i' for invocant of type 'Int' 

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .:<prefix>

A prefix can be called like a method using colonpair notation. For example:

my $a = 1;
say ++$a;       # OUTPUT: «2␤»
say $a.:<++>;   # OUTPUT: «3␤»

Technically, not a real operator; it's syntax special-cased in the compiler.

postfix .::

A class-qualified method call, used to call a method as defined in a parent class or role, even after it has been redefined in the child class.

class Bar {
    method baz { 42 }
class Foo is Bar {
    method baz { "nope" }
say Foo.Bar::baz;       # OUTPUT: «42␤»

Autoincrement Precedence

prefix ++

multi sub prefix:<++>($x is rw) is assoc<non>

Increments its argument by one and returns the updated value.

my $x = 3;
say ++$x;   # OUTPUT: «4␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

prefix --

multi sub prefix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the updated value.

my $x = 3;
say --$x;   # OUTPUT: «2␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

postfix ++

multi sub postfix:<++>($x is rw) is assoc<non>

Increments its argument by one and returns the original value.

my $x = 3;
say $x++;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

Note that this does not necessarily return its argument; e.g., for undefined values, it returns 0:

my $x;
say $x++;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «1␤»

Increment on Str will increment the number part of a string and assign the resulting string to the container. A is rw-container is required.

my $filename = "somefile-001.txt";
say $filename++ for 1..3;
# OUTPUT: «somefile-001.txt␤somefile-002.txt␤somefile-003.txt␤»

postfix --

multi sub postfix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the original value.

my $x = 3;
say $x--;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

Note that this does not necessarily return its argument;e.g., for undefined values, it returns 0:

my $x;
say $x--;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «-1␤»

Decrement on Str will decrement the number part of a string and assign the resulting string to the container. A is rw-container is required. Crossing 0 is prohibited and throws X::AdHoc.

my $filename = "somefile-003.txt";
say $filename-- for 1..3;
# OUTPUT: «somefile-003.txt␤somefile-002.txt␤somefile-001.txt␤»

Exponentiation Precedence

infix **

multi sub infix:<**>(Any, Any --> Numeric:D) is assoc<right>

The exponentiation operator coerces both arguments to Numeric and calculates the left-hand-side raised to the power of the right-hand side.

If the right-hand side is a non-negative integer and the left-hand side is an arbitrary precision type (Int, FatRat), then the calculation is carried out without loss of precision.

Symbolic Unary Precedence

prefix ?

multi sub prefix:<?>(Mu --> Bool:D)

Boolean context operator.

Coerces the argument to Bool by calling the Bool method on it. Note that this collapses Junctions.

prefix !

multi sub prefix:<!>(Mu --> Bool:D)

Negated boolean context operator.

Coerces the argument to Bool by calling the Bool method on it, and returns the negation of the result. Note that this collapses Junctions.

prefix +

multi sub prefix:<+>(Any --> Numeric:D)

Numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it.

prefix -

multi sub prefix:<->(Any --> Numeric:D)

Negative numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it, and then negates the result.

prefix ~

multi sub prefix:<~>(Any --> Str:D)

String context operator.

Coerces the argument to Str by calling the Str method on it.

prefix |

Flattens objects of type Capture, Pair, List, Map and Hash into an argument list.

Outside of argument lists, it returns a Slip, which makes it flatten into the outer list. Inside argument list Positional s are turned into positional arguments and Associative s are turned into named arguments.

prefix ||


prefix +^

multi sub prefix:<+^>(Any --> Int:D)

Integer bitwise negation operator.

Coerces the argument to Int and does a bitwise negation on the result, assuming two's complement.

prefix ~^

Coerces the argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then flips each bit in that buffer.

Please note that this has not yet been implemented.

prefix ?^

multi sub prefix:<?^>(Mu --> Bool:D)

Boolean bitwise negation operator.

Coerces the argument to Bool and then does a bit flip, which makes it the same as prefix:<!> .

prefix ^

multi sub prefix:<^>(Any --> Range:D)

upto operator.

Coerces the argument to Numeric, and generates a range from 0 up to (but excluding) the argument.

say ^5;         # OUTPUT: «0..^5␤»
for ^5 { }      # 5 iterations

Dotty Infix Precedence

These operators are like their Method Postfix counterparts, but require surrounding whitespace (before and/or after) to distinguish them.

infix .=

Calls the right-side method on the value in the left-side container, replacing the resulting value in the left-side container.

In most cases, this behaves identically to the postfix mutator, but the precedence is lower:

my $a = -5 
 say ++$a.=abs 
 # OUTPUT: «6␤» 
 say ++$a .= abs 
 # OUTPUT: «Cannot modify an immutable Int␤ 
 #           in block <unit> at <tmp> line 1␤␤» 

infix .

Calls the following method (whose name must be alphabetic) on the left-side invocant.

Note that the infix form of the operator has a slightly lower precedence than postfix .meth.

say -5.abs;      # like: -(5.abs)
# OUTPUT: «-5␤»
say -5 . abs;    # like: (-5) . abs
# OUTPUT: «5␤»
say -5 .abs;     # following whitespace is optional
# OUTPUT: «5␤»

Multiplicative Precedence

infix *

multi sub infix:<*>(Any, Any --> Numeric:D)

Multiplication operator.

Coerces both arguments to Numeric and multiplies them. The result is of the wider type. See Numeric for details.

infix /

multi sub infix:</>(Any, Any --> Numeric:D)

Division operator.

Coerces both argument to Numeric and divides the left through the right number. Division of Int values returns Rat, otherwise the "wider type" rule described in Numeric holds.

infix div

multi sub infix:<div>(Int:D, Int:D --> Int:D)

Integer division operator. Rounds down.

infix %

multi sub infix:<%>($x, $y --> Numeric:D)

Modulo operator. Coerces to Numeric first.

Generally the following identity holds:

my ($x, $y) = 1,2;
$x % $y == $x - floor($x / $y) * $y

infix %%

multi sub infix:<%%>($a, $b --> Bool:D)

Divisibility operator. Returns True if $a % $b == 0.

infix mod

multi sub infix:<mod>(Int:D $a, Int:D $b --> Int:D)

Integer modulo operator. Returns the remainder of an integer modulo operation.

infix +&

multi sub infix:<+&>($a, $b --> Int:D)

Numeric bitwise AND operator. Coerces both arguments to Int and does a bitwise AND operation assuming two's complement.

infix +<

multi sub infix:<< +< >>($a, $b --> Int:D)

Integer bit shift to the left.

infix +>

multi sub infix:<< +> >>($a, $b --> Int:D)

Integer bit shift to the right.

infix ~&

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise AND on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~<

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise left shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix ~>

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise right shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix gcd

multi sub infix:<gcd>($a, $b --> Int:D)

Coerces both arguments to Int and returns the greatest common divisor.

infix lcm

multi sub infix:<lcm>($a, $b --> Int:D)

Coerces both arguments to Int and returns the least common multiple; that is, the smallest integer that is evenly divisible by both arguments.

Additive Precedence

infix +

multi sub infix:<+>($a, $b --> Numeric:D)

Addition operator.

Coerces both arguments to Numeric and adds them.

infix -

multi sub infix:<->($a, $b --> Numeric:D)

Subtraction operator.

Coerces both arguments to Numeric and subtracts the second from the first.

infix +|

multi sub infix:<+|>($a, $b --> Int:D)

Integer bitwise OR operator.

Coerces both arguments to Int and does a bitwise OR (inclusive OR) operation.

infix +^

multi sub infix:<+^>($a, $b --> Int:D)

Integer bitwise XOR operator.

Coerces both arguments to Int and does a bitwise XOR (exclusive OR) operation.

infix ~|

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise OR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~^

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise XOR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ?|

multi sub infix:<?|>($a, $b --> Bool:D)

Boolean logical OR operator.

Coerces both arguments to Bool and does a logical OR (inclusive OR) operation.

Replication Precedence

infix x

sub infix:<x>($a, $b --> Str:D)

String repetition operator.

Repeats the string $a $b times, if necessary coercing $a to Str and $b Int. Returns an empty string if $b <= 0 .

say 'ab' x 3;           # OUTPUT: «ababab␤»
say 42 x 3;             # OUTPUT: «424242␤»

my $a = 'a'.IO;
my $b = 3.5;
say $a x $b;            # OUTPUT: «aaa␤»

infix xx

multi sub infix:<xx>($a, $b --> List:D)

List repetition operator.

Returns a list of $a repeated and evaluated $b times ($b is coerced to Int). If $b <= 0 , the empty list is returned.

The left-hand side is evaluated for each repetition, so

say [1, 2] xx 5;
# OUTPUT: «([1 2] [1 2] [1 2] [1 2] [1 2])␤»

returns five distinct arrays (but with the same content each time), and

rand xx 3

returns three pseudo random numbers that are determined independently.

The right-hand side can be *, in which case a lazy, infinite list is returned.


infix ~

multi sub infix:<~>(Any,   Any)
multi sub infix:<~>(Str:D, Str:D)
multi sub infix:<~>(Buf:D, Buf:D)

String concatenation operator.

Coerces both arguments to Str and concatenates them. If both arguments are Buf, a combined buffer is returned.

say 'ab' ~ 'c';     # OUTPUT: «abc␤»


multi sub infix:<∘>()
multi sub infix:<∘>(&f)
multi sub infix:<∘>(&f, &g --> Block:D)

Function combinator operator

The function composition operator infix:<∘> or infix:<o> combines two functions, so that the left function is called with the return value of the right function. If the .count of the left function is greater than 1, the return value of the right function will be slipped into the left function.

Both .count and .arity of the right-hand side will be maintained.

sub f($p){ say 'f'; $p / 2 }
sub g($p){ say 'g'; $p * 2 }

my &composed = &f ∘ &g;
say composed 2; # OUTPUT: «g␤f␤2␤»
# equivalent to:
say 2.&g.&f;
# or to:
say f g 2;
sub f($a, $b, $c) { [~] $c, $b, $a } 
 sub g($str){ $str.comb } 
 my &composed = &f ∘ &g; 
 say composed 'abc'; # OUTPUT: «cba␤» 
 # equivalent to: 
 say f |g 'abc'; 

The single-arg candidate returns the given argument as is. The zero-arg candidate returns an identity routine that simply returns its argument.

my &composed = [∘] &uc;
say composed 'foo'; # OUTPUT: «FOO␤»

my &composed = [∘];
say composed 'foo'; # OUTPUT: «foo␤»

Junctive AND (all) Precedence

infix &

multi sub infix:<&>($a, $b --> Junction:D) is assoc<list>

All junction operator.

Creates an all Junction from its arguments. See Junction for more details.

Junctive OR (any) Precedence

infix |

multi sub infix:<|>($a, $b --> Junction:D) is assoc<list>

Any junction operator.

Creates an any Junction from its arguments. See Junction for more details.

infix ^

multi sub infix:<^>($a, $b --> Junction:D) is assoc<list>

One junction operator.

Creates a one Junction from its arguments. See Junction for more details.

Named Unary Precedence

prefix temp

sub prefix:<temp>(Mu $a is rw)

"temporizes" the variable passed as the argument. The variable begins with the same value as it had in the outer scope, but can be assigned new values in this scope. Upon exiting the scope, the variable will be restored to its original value.

my $a = "three";
say $a; # OUTPUT: «three␤»
    temp $a;
    say $a; # OUTPUT: «three␤»
    $a = "four";
    say $a; # OUTPUT: «four␤»
say $a; # OUTPUT: «three␤»

You can also assign immediately as part of the call to temp:

temp $a = "five"; 

Be warned the temp effects get removed once the block is left. If you were to access the value from, say, within a Promise after the temp was undone, you'd get the original value, not the temp one:

my $v = "original"; 
     temp $v = "new one"; 
     start { 
         say "[PROMISE] Value before block is left: `$v`"; 
         sleep 1; 
         say "[PROMISE] Block was left while we slept; value is now `$v`"; 
     sleep ½; 
     say "About to leave the block; value is `$v`"; 
 say "Left the block; value is now `$v`"; 
 sleep 2; 
 # [PROMISE] Value before block is left: `new one` 
 # About to leave the block; value is `new one` 
 # Left the block; value is now `original` 
 # [PROMISE] Block was left while we slept; value is now `original` 

prefix let

sub prefix:<let>(Mu $a is rw)

Restores the previous value if the block exits unsuccessfully. A successful exit means the block returned a defined value or a list.

my $answer = 42;

    let $answer = 84;
    die if not Bool.pick;
    CATCH {
        default { say "it's been reset :(" }
    say "we made it 84 sticks!";

say $answer;

In the above case, if the Bool.pick returns true, the answer will stay as 84 because the block returns a defined value (say returns true). Otherwise the die statement will cause the block to exit unsuccessfully, resetting the answer to 42.

this is duplicated in variables.pod

Nonchaining Binary Precedence

infix does

sub infix:<does>(Mu $obj, Mu $role) is assoc<non>

Mixes $role into $obj at run time. Requires $obj to be mutable.

Similar to but operator, the $role can instead be an instantiated object, in which case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name and that returns $obj:

my $o = class { method Str { "original" } }.new;
put $o;            # OUTPUT: «original␤»
$o does "modded";
put $o;            # OUTPUT: «modded␤»

If methods of the same name are present already, the last mixed in role takes precedence.

infix but

multi sub infix:<but>(Mu $obj1, Mu   $role) is assoc<non>
multi sub infix:<but>(Mu $obj1, Mu:D $obj2) is assoc<non>

Creates a copy of $obj with $role mixed in. Since $obj is not modified, but can be used to created immutable values with mixins.

Instead of a role, you can provide an instantiated object. In this case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name and that returns $obj:

say 42 but 'forty two'; # OUTPUT: «forty two␤» 
 my $s = 12 but class Warbles { method hi { 'hello' } }.new; 
 say $s.Warbles.hi;    # OUTPUT: «hello␤» 
 say $s + 42;          # OUTPUT: «54␤» 

If methods of the same name are present already, the last mixed in role takes precedence. A list of methods can be provided in parentheses separated by comma. In this case conflicts will be reported at runtime.

infix cmp

multi sub infix:<cmp>(Any,       Any)
multi sub infix:<cmp>(Real:D,    Real:D)
multi sub infix:<cmp>(Str:D,     Str:D)
multi sub infix:<cmp>(Version:D, Version:D)

Generic, "smart" three-way comparator.

Compares strings with string semantics, numbers with number semantics, Pair objects first by key and then by value etc.

if $a eqv $b, then $a cmp $b always returns Order::Same.

say (a => 3) cmp (a => 4);   # OUTPUT: «Less␤»
say 4        cmp 4.0;        # OUTPUT: «Same␤»
say 'b'      cmp 'a';        # OUTPUT: «More␤»

infix unicmp

multi sub infix:<unicmp>(Str:D \a, Str:D \b --> Order:D)
multi sub infix:<unicmp>(Pair:D \a, Pair:D \b)

Unlike the cmp operator which sorts according to codepoint, unicmp and coll sort according to how most users would expect, that is, disregarding aspects of the particular character like capitalization.

say 'a' unicmp 'Z'; # Less
say 'a' coll 'Z';   # Less
say 'a' cmp 'Z';    # More

The main difference between coll and unicmp is that the behavior of the former can be changed by the (so far experimental) $*COLLATION dynamic variable.

infix leg

multi sub infix:<leg>(Any,   Any)
multi sub infix:<leg>(Str:D, Str:D)

String three-way comparator. Short for less, equal or greater?.

Coerces both arguments to Str and then does a lexicographic comparison.

say 'a' leg 'b';       # OUTPUT: «Less␤»
say 'a' leg 'a';       # OUTPUT: «Same␤»
say 'b' leg 'a';       # OUTPUT: «More␤»

infix <=>

multi sub infix:«<=>»($a, $b --> Order:D) is assoc<non>

Numeric three-way comparator.

Coerces both arguments to Real and then does a numeric comparison.

infix ..

multi sub infix:<..>($a, $b --> Range:D) is assoc<non>

Range operator

Constructs a Range from the arguments.

infix ..^

multi sub infix:<..^>($a, $b --> Range:D) is assoc<non>

Right-open range operator.

Constructs a Range from the arguments, excluding the end point.

infix ^..

multi sub infix:<^..>($a, $b --> Range:D) is assoc<non>

Left-open range operator.

Constructs a Range from the arguments, excluding the start point.

infix ^..^

multi sub infix:<^..^>($a, $b --> Range:D) is assoc<non>

Open range operator

Constructs a Range from the arguments, excluding both start and end point.

Chaining Binary Precedence

infix ==

multi sub infix:<==>(Any, Any)
multi sub infix:<==>(Int:D, Int:D)
multi sub infix:<==>(Num:D, Num:D)
multi sub infix:<==>(Rational:D, Rational:D)
multi sub infix:<==>(Real:D, Real:D)
multi sub infix:<==>(Complex:D, Complex:D)
multi sub infix:<==>(Numeric:D, Numeric:D)

Numeric equality operator.

Coerces both arguments to Numeric (if necessary); returns True if they are equal.

infix !=

sub infix:<!=>(Mu, Mu --> Bool:D)

Numeric inequality operator.

Coerces both arguments to Numeric (if necessary); returns True if they are distinct.

Is an alias to !==.


Numeric inequality operator.

Equivalent to !=, at codepoint U+2260 (NOT EQUAL TO).

infix <

multi sub infix:«<»(Int:D, Int:D)
multi sub infix:«<»(Num:D, Num:D)
multi sub infix:«<»(Real:D, Real:D)

Numeric less than operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is smaller than the second.

infix <=

multi sub infix:«<=»(Int:D, Int:D)
multi sub infix:«<=»(Num:D, Num:D)
multi sub infix:«<=»(Real:D, Real:D)

Numeric less than or equal to operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is smaller than or equal to the second.


Numeric less than or equal to operator.

Equivalent to <=, at codepoint U+2264 (LESS-THAN OR EQUAL TO).

infix >

multi sub infix:«>»(Int:D, Int:D)
multi sub infix:«>»(Num:D, Num:D)
multi sub infix:«>»(Real:D, Real:D)

Numeric greater than operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is larger than the second.

infix >=

multi sub infix:«>=»(Int:D, Int:D)
multi sub infix:«>=»(Num:D, Num:D)
multi sub infix:«>=»(Real:D, Real:D)

Numeric greater than or equal to operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is larger than or equal to the second.


Numeric greater than or equal to operator.

Equivalent to >=, at codepoint U+2265 (GREATER-THAN OR EQUAL TO).

infix eq

multi sub infix:<eq>(Any,   Any)
multi sub infix:<eq>(Str:D, Str:D)

String equality operator.

Coerces both arguments to Str (if necessary); returns True if both are equal.

Mnemonic: equal

infix ne

multi sub infix:<ne>(Mu,    Mu)
multi sub infix:<ne>(Str:D, Str:D)

String inequality operator.

Coerces both arguments to Str (if necessary); returns False if both are equal.

Mnemonic: not equal

infix gt

multi sub infix:<gt>(Mu,    Mu)
multi sub infix:<gt>(Str:D, Str:D)

String greater than operator.

Coerces both arguments to Str (if necessary); returns True if the first is larger than the second, as determined by lexicographic comparison.

Mnemonic: greater than

infix ge

multi sub infix:<ge>(Mu,    Mu)
multi sub infix:<ge>(Str:D, Str:D)

String greater than or equal to operator.

Coerces both arguments to Str (if necessary); returns True if the first is equal to or larger than the second, as determined by lexicographic comparison.

Mnemonic: greater or equal

infix lt

multi sub infix:<lt>(Mu,    Mu)
multi sub infix:<lt>(Str:D, Str:D)

String less than operator.

Coerces both arguments to Str (if necessary); returns True if the first is smaller than the second, as determined by lexicographic comparison.

Mnemonic: less than

infix le

multi sub infix:<le>(Mu,    Mu)
multi sub infix:<le>(Str:D, Str:D)

String less than or equal to operator.

Coerces both arguments to Str (if necessary); returns True if the first is equal to or smaller than the second, as determined by lexicographic comparison.

Mnemonic: less or equal

infix before

multi sub infix:<before>(Any,       Any)
multi sub infix:<before>(Real:D,    Real:D)
multi sub infix:<before>(Str:D,     Str:D)
multi sub infix:<before>(Version:D, Version:D)

Generic ordering, uses the same semantics as cmp. Returns True if the first argument is smaller than the second.

infix after

multi sub infix:<after>(Any,       Any)
multi sub infix:<after>(Real:D,    Real:D)
multi sub infix:<after>(Str:D,     Str:D)
multi sub infix:<after>(Version:D, Version:D)

Generic ordering, uses the same semantics as cmp. Returns True if the first argument is larger than the second.

infix eqv

sub infix:<eqv>(Any, Any)

Equivalence operator. Returns True if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values.

say [1, 2, 3] eqv [1, 2, 3];    # OUTPUT: «True␤»
say Any eqv Any;                # OUTPUT: «True␤»
say 1 eqv 2;                    # OUTPUT: «False␤»
say 1 eqv 1.0;                  # OUTPUT: «False␤»

Lazy Iterables cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return False if the two lazy Iterables are of different types or if only one Iterable is lazy.

say (1…∞) eqv (1…∞).List; # Both lazy, but different types;   OUTPUT: «False␤»
say (1…∞) eqv (1…3);      # Same types, but only one is lazy; OUTPUT: «False␤»
(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws.
    orelse say $!.^name;  # OUTPUT: «X::Cannot::Lazy␤»

The default eqv operator even works with arbitrary objects. E.g., eqv will consider two instances of the same object as being structurally equivalent:

my class A {
    has $.a;
say => 5) eqv => 5);  # OUTPUT: «True␤»

Although the above example works as intended, the eqv code might fall back to a slower code path in order to do its job. One way to avoid this is to implement an appropriate infix eqv operator:

my class A {
    has $.a;
multi infix:<eqv>(A $l, A $r) { $l.a eqv $r.a }
say => 5) eqv => 5);            # OUTPUT: «True␤»

infix ===

sub infix:<===>(Any, Any)

Value identity operator. Returns True if both arguments are the same object.

my class A { };
my $a =;
say $a === $a;              # OUTPUT: «True␤»
say ===;        # OUTPUT: «False␤»
say A === A;                # OUTPUT: «True␤»

For value types, === behaves like eqv:

say 'a' === 'a';            # OUTPUT: «True␤»
say 'a' === 'b';            # OUTPUT: «False␤»

# different types
say 1 === 1.0;              # OUTPUT: «False␤»

=== uses the WHICH method to obtain the object identity, so all value types must override method WHICH.

infix =:=

multi sub infix:<=:=>(Mu \a, Mu \b)

Container identity operator. Returns True if both arguments are bound to the same container. If it returns True, it generally means that modifying one will also modify the other.

my ($a, $b) = (1, 3);
say $a =:= $b;      # OUTPUT: «False␤»
$b = 2;
say $a;             # OUTPUT: «1␤»
$b := $a;
say $a =:= $b;      # OUTPUT: «True␤»
$a = 5;
say $b;             # OUTPUT: «5␤»

infix ~~

The smart-match operator. Aliases the left-hand side to $_, then evaluates the right-hand side and calls .ACCEPTS($_) on it. The semantics are left to the type of the right-hand side operand.

Here is a partial list of some of the built-in smart-matching functionality. For full details, see ACCEPTS documentation for the type on the right-hand side of the operator.

Right-hand side Comparison semantics
Mu:U type check
Str string equality
Numeric numeric equality
Regex regex match
Callable boolean result of invocation
Set/Bag equal element values
Any:D object identity

infix =~=

multi sub infix:<=~=>(Any, Any)
multi sub infix:<=~=>(Int:D, Int:D)
multi sub infix:<=~=>(Num:D, Num:D)
multi sub infix:<=~=>(Rational:D, Rational:D)
multi sub infix:<=~=>(Real:D, Real:D)
multi sub infix:<=~=>(Complex:D, Complex:D)
multi sub infix:<=~=>(Numeric:D, Numeric:D)

The approximately-equal operator , whose ASCII variant is =~=, calculates the relative difference between the left-hand and right-hand sides and returns True if the difference is less than $*TOLERANCE (which defaults to 1e-15). However, if either side is zero then it checks that the absolute difference between the sides is less than $*TOLERANCE. Note that this operator is not arithmetically symmetrical (doesn't do ± Δ):

my $x = 1;
say ($x + $*TOLERANCE) =~= $x;   # OUTPUT: «False␤»
say ($x - $*TOLERANCE) =~= $x;   # OUTPUT: «True␤»

The tolerance is supposed to be modifiable via an adverb:

RT #128210
my ($x, $y) = 42, 42.1; 
 say $x =~= $y :tolerance(.1); 

However, this is not yet implemented. The same effect can be achieved by assigning to $*TOLERANCE.

    my $*TOLERANCE = .1;
    say 11 =~= 10;        # OUTPUT: «True␤»

Note that setting $*TOLERANCE = 0 will cause all comparisons to fail.

    my $*TOLERANCE = 0;
    say 1 =~= 1;          # OUTPUT: «False␤»

Tight AND Precedence

infix &&

Returns the first argument that evaluates to False in boolean context, otherwise returns the last argument.

Note that this short-circuits, i.e. if one of the arguments evaluates to a false value, the arguments to the right are never evaluated.

sub a { 1 }
sub b { 0 }
sub c { die "never called" };
say a() && b() && c();      # OUTPUT: «0␤»

Tight OR Precedence

infix ||

Returns the first argument that evaluates to True in boolean context, otherwise returns the last argument.

Note that this short-circuits; i.e., if one of the arguments evaluates to a true value, the remaining arguments are not evaluated.

sub a { 0 }
sub b { 1 }
sub c { die "never called" };
say a() || b() || c();      # OUTPUT: «1␤»

infix ^^

Short-circuit exclusive-or. Returns the true argument if there is one (and only one). Returns the last argument if all arguments are false. Returns Nil when more than one argument is true.

This operator short-circuits in the sense that it does not evaluate any arguments after a 2nd true result.

say 0 ^^ 42;                             # OUTPUT: «42␤»
say '' ^^ 0;                             # OUTPUT: «0␤»
say 0 ^^ 42 ^^ 1 ^^ die "never called";  # OUTPUT: «␤»

Note that the semantics of this operator may not be what you assume: infix ^^ flips to the first true value it finds and then flips to Nil forever after the second, no matter how many more true values there are. (In other words, it has "find the one true value" semantics, not "boolean parity" semantics.)

infix //

The defined-or operator or infix // returns the first defined operand, or else the last operand. Short-circuits.

say Any // 0 // 42;         # OUTPUT: «0␤»

infix min

Returns the smallest of the arguments, as determined by cmp semantics.

my $foo = 42;
$foo min= 0   # read as: $foo decreases to 0

infix max

Returns the largest of the arguments, as determined by cmp semantics.

my $foo = -42;
$foo max= 0   # read as: $foo increases to 0

infix minmax

Returns the Range starting from the lowest to the highest of the values, as determined by the cmp semantics. For instance:

# numeric comparison 
 10 minmax 3;     # 3..10 
 # string comparison 
 '10' minmax '3'; # "10".."3" 
 'z' minmax 'k';  # "k".."z" 

If the lowest and highest values coincide, the operator returns a Range made by the same value:

1 minmax 1;  # 1..1 

When applied to Lists, the operator evaluates the lowest and highest values among all available values:

(10,20,30) minmax (0,11,22,33);       # 0..33 
 ('a','b','z') minmax ('c','d','w');   # "a".."z" 

Similarly, when applied to Hashes, it performs a cmp way comparison:

my %winner = points => 30, misses => 10; 
 my %loser = points => 20, misses => 10; 
 %winner cmp %loser;      # More 
 %winner minmax %loser; 
 # ${:misses(10), :points(20)}..${:misses(10), :points(30)} 

Conditional Operator Precedence

infix ?? !!

Also called ternary operator or conditional operator.

$condition ?? $true !! $false evaluates $condition and returns the expression right behind ??, in this case $true if it is True, otherwise evaluates and returns the expression behind !!, $false in this case.

infix ff

sub infix:<ff>(Mu $a, Mu $b)

Also called the flipflop operator.

Compares both arguments to $_ (that is, $_ ~~ $a and $_ ~~ $b). Evaluates to False until the left-hand smartmatch is True, at which point it evaluates to True until the right-hand smartmatch is True.

In effect, the left-hand argument is the "start" condition and the right-hand is the "stop" condition. This construct is typically used to pick up only a certain section of lines. For example:

my $excerpt = q:to/END/; 
 Here's some unimportant text. 
 =begin code 
     This code block is what we're after. 
     We'll use 'ff' to get it. 
 =end code 
 More unimportant text. 
 my @codelines = gather for $excerpt.lines { 
     take $_ if  "=begin code" ff "=end code" 
 # this will print four lines, starting with "=begin code" and ending with 
 # "=end code" 
 say @codelines.join("\n"); 

After matching the start condition, the operator will then match the same $_ to the stop condition and act accordingly if successful. In this example, only the first element is printed:

for <AB C D B E F> {
    say $_ if /A/ ff /B/;  # OUTPUT: «AB␤»

If you only want to test against a start condition and have no stop condition, * can be used as the "stop" condition.

for <A B C D E> {
    say $_ if /C/ ff *;    # OUTPUT: «C␤D␤E␤»

For the sed-like version, which does not try $_ on the stop condition after succeeding on the start condition, see fff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^ff

sub infix:<^ff>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching the start condition (including items also matching the stop condition).

A comparison:

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^ff /C/ for @list;   # OUTPUT: «B␤C␤»

The sed-like version can be found in ^fff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ff^

sub infix:<ff^>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching the stop condition (including items that first matched the start condition).

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ff^ /C/ for @list;   # OUTPUT: «A␤B␤»

The sed-like version can be found in fff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^ff^

sub infix:<^ff^>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching either the stop or start condition (or both).

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^ff^ /C/ for @list;  # OUTPUT: «B␤»

The sed-like version can be found in ^fff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix fff

sub infix:<fff>(Mu $a, Mu $b)

Performs a sed-like flipflop operation, wherein it returns False until the left argument smartmatches against $_, then returns True until the right argument smartmatches against $_.

Works similarly to ff, except that it only tries one argument per invocation. That is, if $_ smartmatches the left argument, fff will not then try to match that same $_ against the right argument.

for <AB C D B E F> {
    say $_ if /A/ fff /B/;         # OUTPUT: «AB␤C␤D␤B␤»

The non-sed-like flipflop (which after successfully matching the left argument against $_ will try that same $_ against the right argument and act accordingly). See ff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^fff

sub infix:<^fff>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to the left argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^fff /C/ for @list;  # OUTPUT: «B␤C␤»

For the non-sed version, see ^ff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix fff^

sub infix:<fff^>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to the right argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ fff^ /C/ for @list;  # OUTPUT: «A␤B␤»

For the non-sed version, see ff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^fff^

sub infix:<^fff^>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to either the left or right argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^fff^ /C/ for @list; # OUTPUT: «B␤»

For the non-sed version, see ^ff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

Item Assignment Precedence

infix =

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

Called the item assignment operator, it Places the value of the right-hand side into the container on the left-hand side. Its exact semantics are left to the container type on the left-hand side.

(Note that item assignment and list assignment have different precedence levels, and the syntax of the left-hand side decides whether an equal sign = is parsed as item assignment or list assignment operator).

infix =>

sub infix:«=>»($key, Mu $value --> Pair:D)

Pair constructor.

Constructs a Pair object with the left-hand side as the key and the right-hand side as the value.

Note that the => operator is syntactically special-cased, in that it allows unquoted identifier on the left-hand side.

my $p = a => 1;
say $p.key;         # OUTPUT: «a␤»
say $p.value;       # OUTPUT: «1␤»

A Pair within an argument list with an unquoted identifier on the left is interpreted as a named argument.

See the Terms language documentation for more ways to create Pair objects.

Loose Unary Precedence

prefix not

multi sub prefix:<not>(Mu $x --> Bool:D)

Evaluates its argument in boolean context (and thus collapses Junctions), and negates the result. Please note that not is easy to misuse. See traps.

prefix so

multi sub prefix:<so>(Mu $x --> Bool:D)

Evaluates its argument in boolean context (and thus collapses Junctions), and returns the result.

Comma Operator Precedence

infix ,

sub infix:<,>(*@a --> List:D) is assoc<list>

Constructs a List from its arguments. Also used syntactically as the separator of arguments in calls.

infix :

Used as an argument separator just like infix , and marks the argument to its left as the invocant. That turns what would otherwise be a function call into a method call.

substr('abc': 1);       # same as 'abc'.substr(1)

Infix : is only allowed after the first argument of a non-method call. In other positions, it's a syntax error.

List Infix Precedence

infix Z

sub infix:<Z>(**@lists --> Seq:D) is assoc<chain>

Zip operator.

Interleaves the lists passed to Z like a zipper, stopping as soon as the first input list is exhausted. The returned Seq contains a nested list with values for all Z operators in a chain.

say (1, 2 Z <a b c> Z <+ ->).perl;  # OUTPUT: «((1, "a", "+"), (2, "b", "-")).Seq␤»
for <a b c> Z <1 2 3> -> [$l, $r] {
    say "$l:$r"
# OUTPUT: «a:1␤b:2␤c:3␤»

The Z operator also exists as a meta operator, in which case the inner lists are replaced by the value from applying the operator to the list:

say 100, 200 Z+ 42, 23;             # OUTPUT: «(142 223)␤»
say 1..3 Z~ <a b c> Z~ 'x' xx 3;    # OUTPUT: «(1ax 2bx 3cx)␤»

infix X

sub infix:<X>(**@lists --> List:D)

Creates a cross product from all the lists, order so that the rightmost elements vary most rapidly:

1..3 X <a b c> X 9
# produces ((1 a 9) (1 b 9) (1 c 9)
#           (2 a 9) (2 b 9) (2 c 9)
#           (3 a 9) (3 b 9) (3 c 9))

The X operator also exists as a meta operator, in which case the inner lists are replaced by the value from applying the operator to the list:

1..3 X~ <a b c> X~ 9
# produces (1a9 1b9 1c9 2a9 2b9 2c9 3a9 3b9 3c9)

infix ...

multi sub infix:<...>(**@) is assoc<list>
multi sub infix:<...^>(**@) is assoc<list>

The sequence operator, which can be written either ... or as (with variants ...^ and …^) will produce generic sequences on demand.

The left-hand side will always include initial elements; it may include a generator too. The right-hand side will have an endpoint, which can be Inf or * for "infinite" lists (whose elements are only produced on demand), an expression which will end the sequence when True, or other elements such as Junctions.

The sequence operator invokes the generator with as many arguments as necessary. The arguments are taken from the initial elements and the already generated elements. The default generator is *.succ or *.pred, depending on how the end points compare:

say 1 ... 4;        # OUTPUT: «(1 2 3 4)␤»
say 4 ... 1;        # OUTPUT: «(4 3 2 1)␤»
say 'a' ... 'e';    # OUTPUT: «(a b c d e)␤»
say 'e' ... 'a';    # OUTPUT: «(e d c b a)␤»

An endpoint of * (Whatever), Inf or generates on demand an infinite sequence, with a default generator of *.succ

say (1 ... *)[^5];  # OUTPUT: «(1 2 3 4 5)␤»

Custom generators need to be the last argument before the '...' operator. This one takes two arguments, and generates the Fibonacci numbers

say (1, 1, -> $a, $b { $a + $b } ... *)[^8];    # OUTPUT: «(1 1 2 3 5 8 13 21)␤»
# same but shorter
say (1, 1, * + * ... *)[^8];                    # OUTPUT: «(1 1 2 3 5 8 13 21)␤»

Of course the generator can also take only one argument.

say 5, { $_ * 2 } ... 40;                       # OUTPUT: «5 10 20 40␤»

There must be at least as many initial elements as arguments to the generator.

Without a generator and with more than one initial element and all initial elements numeric, the sequence operator tries to deduce the generator. It knows about arithmetic and geometric sequences.

say 2, 4, 6 ... 12;     # OUTPUT: «(2 4 6 8 10 12)␤»
say 1, 2, 4 ... 32;     # OUTPUT: «(1 2 4 8 16 32)␤»

If the endpoint is not *, it's smart-matched against each generated element and the sequence is terminated when the smart-match succeeded. For the ... operator, the final element is included, for the ...^ operator it's excluded.

This allows you to write

say 1, 1, * + * ...^ *>= 100;

To generate all Fibonacci numbers up to but excluding 100.

The ... operators consider the initial values as "generated elements" as well, so the are also checked against the endpoint:

my $end = 4;
say 1, 2, 4, 8, 16 ... $end;
# OUTPUT: «(1 2 4)␤»

List Prefix Precedence

infix =

List assignment operator. Its exact semantics are left to the container type on the left-hand side. See Array and Hash for common cases.

The distinction between item assignment and list assignment is determined by the parser depending on the syntax of the left-hand side.

infix :=

Binding operator. Whereas $x = $y puts the value in $y into $x, $x := $y makes $x and $y the same thing.

my $a = 42;
my $b = $a;
say $a;

This will output 42, because $a and $b both contained the number 42, but the containers were different.

my $a = 42;
my $b := $a;
say $a;

This will output 43, since $b and $a both represented the same object.

If type constrains on variables or containers are present a type check will be performed at runtime. On failure X::TypeCheck::BindingType will be thrown.

Please note that := is a compile time construct. As such it can not be referred to at runtime and thus can't be used as an argument to meta operators.

infix ::=

Read-only binding operator, not yet implemented in Rakudo. See infix :=.

listop ...

The yada, yada, yada operator or stub operator. If it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the ... statement is executed, it calls fail, with the default message stub code executed.

listop !!!

Fatal stub operator.

If it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the !!! statement is executed, it calls die, with the default message stub code executed.

listop ???

Admonitory stub operator.

If it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the ??? statement is executed, it calls warn, with the default message stub code executed.

Reduction operators

Any infix operator (except for non-associating operators) can be surrounded by square brackets in term position to create a list operator that reduces using that operation.

say [+] 1, 2, 3;      # 1 + 2 + 3 = 6
my @a = (5, 6);
say [*] @a;           # 5 * 6 = 30

Reduction operators have the same associativity as the operators they are based on.

say [-] 4, 3, 2;      # 4-3-2 = (4-3)-2 = -1
say [**] 4, 3, 2;     # 4**3**2 = 4**(3**2) = 262144

Loose AND precedence

infix and

Same as infix &&, except with looser precedence.

Short-circuits so that it returns the first operand that evaluates to False, otherwise returns the last operand. Note that and is easy to misuse. See traps.

infix andthen

The andthen operator returns Empty upon encountering the first undefined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as arguments if the right side is a Callable, whose count must be 0 or 1.

A handy use of this operator is to alias a routine's return value to $_ and to do additional manipulation with it, such as printing or returning it to caller. Since the andthen operator short-circuits, statements on the right-hand side won't get executed, unless left-hand side is defined (tip: Failures are never defined, so you can handle them with this operator).

sub load-data {
    rand  > .5 or return; # simulated load data failure; return Nil
    (rand > .3 ?? 'error' !! 'good data') xx 10 # our loaded data
load-data.first: /good/ andthen say "$_ is good";
# OUTPUT: «(good data is good)␤»

load-data() andthen .return; # return loaded data, if it's defined
die "Failed to load data!!";

The above example will print good data is good only if the subroutine returned any items that match /good/ and will die unless loading data returned a defined value. The aliasing behaviour lets us pipe the values across the operator.

The andthen operator is a close relative of with statement modifier, and some compilers compile with to andthen, meaning these two lines have equivalent behaviour:

.say with 42;
42 andthen .say;

infix notandthen

The notandthen operator returns Empty upon encountering the first defined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as arguments if the right side is a Callable, whose count must be 0 or 1.

At first glance, notandthen might appear to be the same thing as the orelse operator. The difference is subtle: notandthen returns Empty when it encounters a defined item (that isn't the last item), whereas orelse returns that item. In other words, notandthen is a means to act when items aren't defined, whereas orelse is a means to obtain the first defined item:

sub all-sensors-down     { [notandthen] |@_, True             } 
 sub first-working-sensor { [orelse]     |@_, 'default sensor' } 
 all-sensors-down Nil, Nil, Nil 
   and say 'OMG! All sensors are down!'; # OUTPUT:«OMG! All sensors are down!␤» 
 say first-working-sensor Nil, Nil, Nil; # OUTPUT:«default sensor␤» 
 all-sensors-down Nil, 42, Nil 
   and say 'OMG! All sensors are down!'; # No output 
 say first-working-sensor Nil, 42, Nil;  # OUTPUT:«42␤» 

The andthen operator is a close relative of without statement modifier, and some compilers compile without to notandthen, meaning these two lines have equivalent behaviour:

sub good-things { fail } 
 'boo'.say without good-things; 
 good-things() notandthen 'boo'.say; 

Loose OR Precedence

infix or

Same as infix ||, except with looser precedence.

Returns the first argument that evaluates to True in boolean context, or otherwise the last argument, it short-circuits. Please note that or is easy to misuse. See traps.

infix orelse

The orelse operator is similar to infix //, except with looser precedence and $_ aliasing.

Returns the first defined argument, or else the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as an argument if the right side is a Callable, whose count must be 0 or 1.

This operator is useful for handling Failures returned by routines since the expected value is usually defined and Failure never is:

sub meows { ++$ < 4 ?? fail 'out of meows!' !! '🐱' }

sub meows-processor1 { meows() orelse .return } # return handled Failure
sub meows-processor2 { meows() orelse fail $_ } # return re-armed Failure
sub meows-processor3 {
    # Use non-Failure output, or else print a message that stuff's wrong
    meows() andthen .say orelse ‘something's wrong’.say;

say "{.^name}, {.handled}"  # OUTPUT: «Failure, True␤»
    given meows-processor1;
say "{.^name}, {.handled}"  # OUTPUT: «Failure, False␤»
    given meows-processor2;
meows-processor3;           # OUTPUT: «something's wrong␤»
meows-processor3;           # OUTPUT: «🐱␤»

infix xor

Same as infix ^^, except with looser precedence.

Returns the operand that evaluates to True in boolean context, if and only if the other operand evaluates to False in boolean context. If both operands evaluate to False, returns the last argument. If both operands evaluate to True, returns Nil.

When chaining, returns the operand that evaluates to True, if and only if there is one such operand. If more than one operand is true, it short-circuits after evaluating the second and returns Nil. If all operands are false, returns the last one.

Sequencer Precedence

infix ==>

This feed operator takes the result from the left and passes it to the next (right) routine as the last parameter.

The precedence is very loose so you will need to use parentheses to assign the result or you can even just use another feed operator! In the case of routines/methods that take a single argument or where the first argument is a block, it's often required that you call with parentheses (though this is not required for the very last routine/method).

This "traditional" structure, read bottom-to-top, with the last two lines creating the data structure that is going to be processed

my @result = map { .uniparse },                    # (3) Converts to unicode
    grep { .uniparse },                            # (2) Checks if it parses
    map( {"VULGAR FRACTION " ~ $^þ }, @fractions); # (1) Adds string to input

# @result is [⅖ ⅗ ⅜ ⅘ ⅚ ⅝ ⅞]

Now we use the feed operator (left-to-right) with parentheses, read top-to-bottom

my @result = (
    ==> map( {"VULGAR FRACTION " ~ $^þ } )                         # (2) Converts to Unicode name
    ==> grep({ .uniparse })                                        # (3) Filters only real names
    ==> map( { .uniparse} );                                       # (4) Converts to unicode

For illustration, method chaining equivalent, read top-to-bottom, using the same sequence as above

    .map( {"VULGAR FRACTION " ~ $^þ } )
    .grep({ .uniparse })
    .map({ .uniparse });

Although in this particular case the result is the same, the feed operator ==> more clearly shows intent with arrow pointing the data flow. To assign without the need of parentheses use another feed operator

my @result;
<people of earth>
    ==> map({ .tc })
    ==> grep /<[PE]>/
    ==> sort()
    ==> @result;

It can be useful to capture a partial result, however, unlike the leftward feed operator, it does require parentheses or a semicolon

my @result;
<people of earth>
    ==> map({ .tc })
    ==> my @caps; @caps   # also could wrap in parentheses instead
    ==> grep /<[PE]>/
    ==> sort()
    ==> @result;

The feed operator lets you construct method-chaining-like patterns out of routines and the results of methods on unrelated data. In method-chaining, you are restricted to the methods available on the data or the result of previous method call. With feed operators, that restriction is gone. The resulting code could also be seen to be more readable than a series of method calls broken over multiple lines.

Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the left operand is enclosable as a closure (that can be cloned and run in a subthread).

infix <==

This leftward feed operator takes the result from the right and passes it to the previous (left) routine as the last parameter. This elucidates the right-to-left dataflow for a series of list manipulating functions.

# Traditional structure, read bottom-to-top
my @result =
    sort                   # (4) Sort, result is <Earth People>
    grep { /<[PE]>/ },     # (3) Look for P or E
    map { .tc },           # (2) Capitalize the words
    <people of earth>;     # (1) Start with the input

# Feed (right-to-left) with parentheses, read bottom-to-top
my @result = (
    sort()                 # (4) Sort, result is <Earth People>
    <== grep({ /<[PE]>/ }) # (3) Look for P or E
    <== map({ .tc })       # (2) Capitalize the words
    <== <people of earth>  # (1) Start with the input

# To assign without parentheses, use another feed operator
my @result
    <== sort()              # (4) Sort, result is <Earth People>
    <== grep({ /<[PE]>/ })  # (3) Look for P or E
    <== map({ .tc })        # (2) Capitalize the words
    <== <people of earth>;  # (1) Start with the input

# It can be useful to capture a partial result
my @result
    <== sort()
    <== grep({ /<[PE]>/ })
    <== my @caps            # unlike ==>, there's no need for additional statement
    <== map({ .tc })
    <== <people of earth>;

Unlike the rightward feed operator, the result is not closely mappable to method-chaining. However, compared to the traditional structure above where each argument is separated by a line, the resulting code is more demonstrative than commas. The leftward feed operator also allows you to "break into" the statement and capture an intermediary result which can be extremely useful for debugging or to take that result and create another variation on the final result.

Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the right operand is enclosable as a closure (that can be cloned and run in a subthread).

34 Packages

Organizing and referencing namespaced program elements

* Take a lot of stuff from S02 for this * Document 'import'

Packages are nested namespaces of named program elements. Modules, classes, grammars, and others are types of packages. Like files in a directory, you can generally refer to named elements with their short-name if they are local, or with a longer name to disambiguate.


A name is anything that is a legal part of a variable name (not counting the sigil). This includes:

$foo                # simple identifiers 
 $Foo::Bar::baz      # compound identifiers separated by :: 
 $Foo::($bar)::baz   # compound identifiers that perform interpolations 
 $42                 # numeric names 
 $!                  # certain punctuation variables 

:: is used to separate nested package names.

Package-qualified names

Ordinary package-qualified names look like:

$Foo::Bar::baz      # the $baz variable in package Foo::Bar

Sometimes it's clearer to keep the sigil with the variable name, so an alternate way to write this is:


This is resolved at compile time because the variable name is a constant.

If the name part before :: is null, it means the package is unspecified and must be searched for. Generally this means that an initial :: following the main sigil is a no-op on names that are known at compile time, though ::() can also be used to introduce an interpolation. Also, in the absence of another sigil, :: can serve as its own sigil indicating intentional use of a not-yet-declared package name.


The following pseudo-package names are reserved at the front of a name:

MY Symbols in the current lexical scope (aka $?SCOPE)
OUR Symbols in the current package (aka $?PACKAGE)
CORE Outermost lexical scope, definition of standard Perl
GLOBAL Interpreter-wide package symbols, really UNIT::GLOBAL
PROCESS Process-related globals (superglobals). The last place dynamic variable
lookup will look.
COMPILING Lexical symbols in the scope being compiled

The following relative names are also reserved but may be used anywhere in a name:

CALLER Contextual symbols in the immediate caller's lexical scope
CALLERS Contextual symbols in any caller's lexical scope
DYNAMIC Contextual symbols in my or any caller's lexical scope
OUTER Symbols in the next outer lexical scope
OUTERS Symbols in any outer lexical scope
LEXICAL Contextual symbols in my or any outer's lexical scope
UNIT Symbols in the outermost lexical scope of compilation unit
SETTING Lexical symbols in the unit's DSL (usually CORE)
PARENT Symbols in this package's parent package (or lexical scope)
CLIENT The nearest CALLER that comes from a different package

The file's scope is known as UNIT, but there are one or more lexical scopes outside of that corresponding to the linguistic setting (often known as the prelude in other cultures). Hence, the SETTING scope is equivalent to UNIT::OUTERS. For a standard Perl program SETTING is the same as CORE, but various startup options (such as -n or -p) can put you into a domain specific language, in which case CORE remains the scope of the standard language, while SETTING represents the scope defining the DSL that functions as the setting of the current file. When used as a search term in the middle of a name, SETTING includes all its outer scopes up to CORE. To get only the setting's outermost scope, use UNIT::OUTER instead.

Looking up names

Interpolating into names

You may interpolate a string into a package or variable name using ::($expr) where you'd ordinarily put a package or variable name. The string is allowed to contain additional instances of ::, which will be interpreted as package nesting. You may only interpolate entire names, since the construct starts with ::, and either ends immediately or is continued with another :: outside the parentheses. Most symbolic references are done with this notation:

$foo = "Bar"; 
 $foobar = "Foo::Bar"; 
 $::($foo)           # lexically-scoped $Bar 
 $::("MY::$foo")     # lexically-scoped $Bar 
 $::("OUR::$foo")    # package-scoped $Bar 
 $::("GLOBAL::$foo") # global $Bar 
 $::("PROCESS::$foo")# process $Bar 
 $::("PARENT::$foo") # current package's parent's $Bar 
 $::($foobar)        # $Foo::Bar 
 $::($foobar)::baz   # $Foo::Bar::baz 
 $::($foo)::Bar::baz # $Bar::Bar::baz 
 $::($foobar)baz     # ILLEGAL at compile time (no operator baz) 

An initial :: doesn't imply global. Here as part of the interpolation syntax it doesn't even imply package. After the interpolation of the ::() component, the indirect name is looked up exactly as if it had been there in the original source code, with priority given first to leading pseudo-package names, then to names in the lexical scope (searching scopes outwards, ending at CORE). The current package is searched last.

Use the MY pseudopackage to limit the lookup to the current lexical scope, and OUR to limit the scopes to the current package scope.

In the same vein, class and method names can be interpolated too.

role with-method {
    method a-method { return "in-a-method of " ~ $?CLASS.^name  };

class a-class does with-method {
    method another-method { return 'in-another-method' };

class b-class does with-method {};

my $what-class='a-class';

say ::($what-class).a-method;
$what-class = 'b-class';
say ::($what-class).a-method;

my $what-method='a-method';
say a-class."$what-method"();
say a-class."$what-method"();

Direct lookup

To do direct lookup in a package's symbol table without scanning, treat the package name as a hash:

Foo::Bar::{'&baz'}  # same as &Foo::Bar::baz 
 PROCESS::<$IN>      # Same as $*IN 
 Foo::<::Bar><::Baz> # same as Foo::Bar::Baz 

Unlike ::() symbolic references, this does not parse the argument for ::, nor does it initiate a namespace scan from that initial point. In addition, for constant subscripts, it is guaranteed to resolve the symbol at compile time.

The null pseudo-package is the same search list as an ordinary name search. That is, the following are all identical in meaning:


Each of them scans lexical scopes outward, and then the current package scope (though the package scope is then disallowed when "strict" is in effect).

As a result of these rules, you can write any arbitrary variable name as either of:


You can also use the ::<> form as long as there are no spaces in the name.

Package lookup

Subscript the package object itself as a hash object, the key of which is the variable name, including any sigil. The package object can be derived from a type name by use of the :: postfix:


Class member lookup

Methods—including auto-generated methods, such as public attributes' accessors—are stored in the class meta object and can be looked up through by the lookup method.



Interpreter globals live in the GLOBAL package. The user's program starts in the GLOBAL package, so "our" declarations in the mainline code go into that package by default. Process-wide variables live in the PROCESS package. Most predefined globals such as $*UID and $*PID are actually process globals.


Any package may have a Version object attached to it. This object can be accessed via $?PACKAGE.^ver or from outside the package Fully::Qualified::Name.^ver.

35 Performance

Measuring and improving run-time or compile-time performance

This page is about computer performance in the context of Perl 6.

First, profile your code

Make sure you're not wasting time on the wrong code: start by identifying your "critical 3%" by "profiling" your code's performance. The rest of this document shows you how to do that.

Time with now - INIT now

Expressions of the form now - INIT now, where INIT is a phase in the running of a Perl 6 program, provide a great idiom for timing code snippets.

Use the m: your code goes here #perl6 channel evalbot to write lines like:

m: say now - INIT now 
 rakudo-moar abc1234: OUTPUT«0.0018558␤» 

The now to the left of INIT runs 0.0018558 seconds later than the now to the right of the INIT because the latter occurs during the INIT phase.

Profile locally

When using the MoarVM backend, the Rakudo compiler's --profile command line option writes the profile data to an HTML file.

This file will open to the "Overview" section, which gives some overall data about how the program ran, e.g., total run time, time spent doing garbage collection. One important piece of information you'll get here is percentage of the total call frames (i.e., blocks) that were interpreted (slowest, in red), speshed (faster, in orange), and JITted (fastest, in green).

The next section, "Routines", is probably where you'll spend the most time. It has a sortable and filterable table of routine (or block) name+file+line, the number of times it ran, the inclusive time (time spent in that routine + time spent in all routines called from it), exclusive time (just the time spent in that routine), and whether it was interpreted, speshed, or JITted (same color code as the "Overview" page). Sorting by exclusive time is a good way to know where to start optimizing. Routines with a filename that starts like SETTING::src/core/ or gen/moar/ are from the compiler, a good way to just see the stuff from your own code is to put the filename of the script you profiled in the "Name" search box.

The "Call Graph" section gives a flame graph representation of much of the same information as the "Routines" section.

The "Allocations" section gives you information about the amount of different types that were allocated, as well as which routines did the allocating.

The "GC" section gives you detailed information about all the garbage collections that occurred.

The "OSR / Deopt" section gives you information about On Stack Replacements (OSRs), which is when routines are "upgraded" from interpreted to speshed or JITted. Deopts are the opposite, when speshed or JITted code has to be "downgraded" to being interpreted.

If the profile data is too big, it could take a long time for a browser to open the file. In that case, output to a file with a .json extension using the --profile-filename option, then open the file with the Qt viewer.

To deal with even larger profiles, output to a file with a .sql extension. This will write the profile data as a series of SQL statements, suitable for opening in SQLite.

# create a profile 
 perl6 --profile --profile-filename=demo.sql -e 'say (^20).combinations(3).elems' 
 # create a SQLite database 
 sqlite3 demo.sqlite 
 # load the profile data 
 sqlite> .read demo.sql 
 # the query below is equivalent to the default view of the "Routines" tab in the HTML profile 
 sqlite> select 
       case when = "" then "<anon>" else end as name, 
       sum(entries) as entries, 
       sum(case when rec_depth = 0 then inclusive_time else 0 end) as inclusive_time, 
       sum(exclusive_time) as exclusive_time 
       calls c, 
       routines r 
     where = 
     group by 
     order by 
       inclusive_time desc 
     limit 30; 

To learn how to interpret the profile info, use the prof-m: your code goes here evalbot (explained above) and ask questions on the IRC channel.

Profile compiling

If you want to profile the time and memory it takes to compile your code, use Rakudo's --profile-compile or --profile-stage options.

Create or view benchmarks

Use perl6-bench.

If you run perl6-bench for multiple compilers (typically, versions of Perl 5, Perl 6, or NQP), results for each are visually overlaid on the same graphs, to provide for quick and easy comparison.

Share problems

Once you've used the above techniques to identify the code to improve, you can then begin to address (and share) the problem with others:

Solve problems

This bears repeating: make sure you're not wasting time on the wrong code. Start by identifying the "critical 3%" of your code.

Line by line

A quick, fun, productive way to try improve code line-by-line is to collaborate with others using the #perl6 evalbot camelia.

Routine by routine

With multidispatch, you can drop in new variants of routines "alongside" existing ones:

# existing code generically matches a two arg foo call:
multi sub foo(Any $a, Any $b) { ... }

# new variant takes over for a foo("quux", 42) call:
multi sub foo("quux", Int $b) { ... }

The call overhead of having multiple foo definitions is generally insignificant (though see discussion of where below), so if your new definition handles its particular case more efficiently than the previously existing set of definitions, then you probably just made your code that much more efficient for that case.

Speed up type-checks and call resolution

Most where clauses – and thus most subsets – force dynamic (run-time) type checking and call resolution for any call it might match. This is slower, or at least later, than compile-time.

Method calls are generally resolved as late as possible (dynamically at run-time), whereas sub calls are generally resolved statically at compile-time.

Choose better algorithms

One of the most reliable techniques for making large performance improvements, regardless of language or compiler, is to pick a more appropriate algorithm.

A classic example is Boyer-Moore. To match a small string in a large string, one obvious way to do it is to compare the first character of the two strings and then, if they match, compare the second characters, or, if they don't match, compare the first character of the small string with the second character in the large string, and so on. In contrast, the Boyer-Moore algorithm starts by comparing the *last* character of the small string with the correspondingly positioned character in the large string. For most strings, the Boyer-Moore algorithm is close to N times faster algorithmically, where N is the length of the small string.

The next couple sections discuss two broad categories for algorithmic improvement that are especially easy to accomplish in Perl 6. For more on this general topic, read the wikipedia page on algorithmic efficiency, especially the 'See also' section near the end.

Change sequential/blocking code to parallel/non-blocking

This is another very important class of algorithmic improvement.

See the slides for Parallelism, Concurrency, and Asynchrony in Perl 6 and/or the matching video.

Use existing high performance code

There are plenty of high performance C libraries that you can use within Perl 6 and NativeCall makes it easy to create wrappers for them. There's experimental support for C++ libraries, too.

If you want to use Perl 5 modules in Perl 6, mix in Perl 6 types and the Meta-Object Protocol.

More generally, Perl 6 is designed to smoothly interoperate with other languages and there are a number of modules aimed at facilitating the use of libs from other langs.

Make the Rakudo compiler generate faster code

To date, the focus for the compiler has been correctness, not how fast it generates code or how fast or lean the code it generates runs. But that's expected to change, eventually... You can talk to compiler devs on the freenode IRC channels #perl6 and #moarvm about what to expect. Better still, you can contribute yourself:

Still need more ideas?

Some known current Rakudo performance weaknesses not yet covered in this page include the use of gather/take, junctions, regexes and string handling in general.

If you think some topic needs more coverage on this page, please submit a PR or tell someone your idea. Thanks. :)

Not getting the results you need/want?

If you've tried everything on this page to no avail, please consider discussing things with a compiler dev on #perl6, so we can learn from your use-case and what you've found out about it so far.

Once a dev knows of your plight, allow enough time for an informed response (a few days or weeks, depending on the exact nature of your problem and potential solutions).

If that hasn't worked out, please consider filing an issue about your experience at our user experience repo before moving on.

Thanks. :)

36 Phasers

Program execution phases and corresponding phaser blocks

The lifetime (execution timeline) of a program is broken up into phases. A phaser is a block of code called during a specific execution phase.


A phaser block is just a trait of the closure containing it, and is automatically called at the appropriate moment. These auto-called blocks are known as phasers, since they generally mark the transition from one phase of computing to another. For instance, a CHECK block is called at the end of compiling a compilation unit. Other kinds of phasers can be installed as well; these are automatically called at various times as appropriate, and some of them respond to various control exceptions and exit values. For instance, some phasers might be called if the exit from a block is successful or not, with success in this case defined by returning with a defined value or list without any Failure or exception in the process.

Here is a summary:

  BEGIN {...} #  * at compile time, ASAP, only ever runs once 
   CHECK {...} #  * at compile time, ALAP, only ever runs once 
    INIT {...} #  * at run time, ASAP, only ever runs once 
     END {...} #  at run time, ALAP, only ever runs once 
   ENTER {...} #  * at every block entry time, repeats on loop blocks. 
   LEAVE {...} #  at every block exit time (even stack unwinds from exceptions) 
    KEEP {...} #  at every successful block exit, part of LEAVE queue 
    UNDO {...} #  at every unsuccessful block exit, part of LEAVE queue 
   FIRST {...} #  at loop initialization time, before any ENTER 
    NEXT {...} #  at loop continuation time, before any LEAVE 
    LAST {...} #  at loop termination time, after any LEAVE 
     PRE {...} #  assert precondition at every block entry, before ENTER 
    POST {...} #  assert postcondition at every block exit, after LEAVE 
   CATCH {...} #  catch exceptions, before LEAVE 
 CONTROL {...} #  catch control exceptions, before LEAVE 
    LAST {...} #  supply tapped by whenever-block is done, runs very last 
    QUIT {...} #  catch async exceptions within a whenever-block, runs very last 
 COMPOSE {...} #  when a role is composed into a class 
   CLOSE {...} #  appears in a supply block, called when the supply is closed 

Phasers marked with a * have a run-time value, and if evaluated earlier than their surrounding expression, they simply save their result for use in the expression later when the rest of the expression is evaluated:

my $compiletime = BEGIN { now };
our $random = ENTER { rand };

As with other statement prefixes, these value-producing constructs may be placed in front of either a block or a statement:

my $compiletime = BEGIN now;
our $random = ENTER rand;

Most of these phasers will take either a block or a function reference. The statement form can be particularly useful to expose a lexically scoped declaration to the surrounding lexical scope without "trapping" it inside a block.

These declare the same variables with the same scope as the preceding example, but run the statements as a whole at the indicated time:

BEGIN my $compiletime = now;
ENTER our $random = rand;

(Note, however, that the value of a variable calculated at compile time may not persist under run-time cloning of any surrounding closure.)

Most of the non-value-producing phasers may also be so used:

END say my $accumulator;

Note, however, that

END say my $accumulator = 0;

sets the variable to 0 at END time, since that is when the "my" declaration is actually executed. Only argumentless phasers may use the statement form. This means that CATCH and CONTROL always require a block, since they take an argument that sets $_ to the current topic, so that the innards are able to behave as a switch statement. (If bare statements were allowed, the temporary binding of $_ would leak out past the end of the CATCH or CONTROL, with unpredictable and quite possibly dire consequences. Exception handlers are supposed to reduce uncertainty, not increase it.)

Some of these phasers also have corresponding traits that can be set on variables; they use will followed by the name of the phaser in lowercase. These have the advantage of passing the variable in question into the closure as its topic:

our $h will enter { .rememberit() } will undo { .forgetit() };

Only phasers that can occur multiple times within a block are eligible for this per-variable form; this excludes CATCH and others like CLOSE or QUIT.

The topic of the block outside a phaser is still available as OUTER::<$_> . Whether the return value is modifiable may be a policy of the phaser in question. In particular, the return value should not be modified within a POST phaser, but a LEAVE phaser could be more liberal.

Any phaser defined in the lexical scope of a method is a closure that closes over self as well as normal lexicals. (Or equivalently, an implementation may simply turn all such phasers into submethods whose primed invocant is the current object.)

When multiple phasers are scheduled to run at the same moment, the general tiebreaking principle is that initializing phasers execute in order declared, while finalizing phasers execute in the opposite order, because setup and teardown usually want to happen in the opposite order from each other.

Execution Order

Compilation Begins

      BEGIN {...} #  at compile time, ASAP, only ever runs once 
       CHECK {...} #  at compile time, ALAP, only ever runs once 
     COMPOSE {...} #  when a role is composed into a class 

Execution Begins

       INIT {...} #  at run time, ASAP, only ever runs once 

Before block execution begins

        PRE {...} #  assert precondition at every block entry, before ENTER 

Loop execution begins

      FIRST {...} #  at loop initialization time, before any ENTER 

Block execution begins

      ENTER {...} #  at every block entry time, repeats on loop blocks. 

Exception maybe happens

      CATCH {...} #  catch exceptions, before LEAVE 
     CONTROL {...} #  catch control exceptions, before LEAVE 

End of loop, either continuing or finished

       NEXT {...} #  at loop continuation time, before any LEAVE 
        LAST {...} #  at loop termination time, after any LEAVE 

End of block

      LEAVE {...} #  at every block exit time (even stack unwinds from exceptions) 
        KEEP {...} #  at every successful block exit, part of LEAVE queue 
        UNDO {...} #  at every unsuccessful block exit, part of LEAVE queue 

Postcondition for block

       POST {...} #  assert postcondition at every block exit, after LEAVE 

Async whenever-block is complete

       LAST {...} #  if ended normally with done, runs once after block 
        QUIT {...} #  catch async exceptions 

Program terminating

        END {...} #  at run time, ALAP, only ever runs once 

Program Execution Phasers


Runs at compile time, as soon as possible, only runs once.

Can have a return value that is provided even in later phases.


Runs at compile time, As late as possible, only runs once.

Can have a return value that is provided even in later phases.

Code that is generated at run time can still fire off CHECK and INIT phasers, though of course those phasers can't do things that would require travel back in time. You need a wormhole for that.


Runs after compilation during main execution, as soon as possible, only runs once.

Can have a return value that is provided even in later phases.

When phasers are in different modules, the INIT and END phasers are treated as if declared at use time in the using module. (It is erroneous to depend on this order if the module is used more than once, however, since the phasers are only installed the first time they're noticed.)

Code that is generated at run time can still fire off CHECK and INIT phasers, though of course those phasers can't do things that would require travel back in time. You need a wormhole for that.

An INIT only runs once for all copies of a cloned closure.


Runs after compilation during main execution, as late as possible, only runs once.

When phasers are in different modules, the INIT and END phasers are treated as if declared at use time in the using module. (It is erroneous to depend on this order if the module is used more than once, however, since the phasers are only installed the first time they're noticed.)


Appears in a supply block. Called when the supply is closed.

Block Phasers

Execution in the context of a block has its own phases.

Block-leaving phasers wait until the call stack is actually unwound to run. Unwinding happens only after some exception handler decides to handle the exception that way. That is, just because an exception is thrown past a stack frame does not mean we have officially left the block yet, since the exception might be resumable. In any case, exception handlers are specified to run within the dynamic scope of the failing code, whether or not the exception is resumable. The stack is unwound and the phasers are called only if an exception is not resumed.

These can occur multiple times within the block. So they aren't really traits, exactly--they add themselves onto a list stored in the actual trait. If you examine the ENTER trait of a block, you'll find that it's really a list of phasers rather than a single phaser.

All of these phaser blocks can see any previously declared lexical variables, even if those variables have not been elaborated yet when the closure is invoked (in which case the variables evaluate to an undefined value.)


Runs at every block entry time, repeats on loop blocks.

Can have a return value that is provided even in later phases.

An exception thrown from an ENTER phaser will abort the ENTER queue, but one thrown from a LEAVE phaser will not.


Runs at every block exit time (even stack unwinds from exceptions), except when the program exits abruptly (e.g. with exit).

LEAVE phasers for a given block are necessarily evaluated after any CATCH and CONTROL phasers. This includes the LEAVE variants, KEEP and UNDO. POST phasers are evaluated after everything else, to guarantee that even LEAVE phasers can't violate postconditions.

An exception thrown from an ENTER phaser will abort the ENTER queue, but one thrown from a LEAVE phaser will not.

If a POST fails or any kind of LEAVE block throws an exception while the stack is unwinding, the unwinding continues and collects exceptions to be handled. When the unwinding is completed all new exceptions are thrown from that point.

sub answer() {
    LEAVE say „I say after the return value.“;

    42 # this is the return value

Note: be mindful of LEAVE phasers directly in blocks of routines, as they will get executed even when an attempt to call the routine with wrong arguments is made:

sub foo (Int) {
    say "Hello!";
    LEAVE say "oh noes!"
try foo rand; # OUTPUT: «oh noes!␤»

Although the subroutine's body did not get run, because the sub expects an Int and rand returned a Num, its block was entered and left (when param binding failed), and so the LEAVE phaser was run.


Runs at every successful block exit, as part of the LEAVE queue (shares the same order of execution).

For phasers such as KEEP and POST that are run when exiting a scope normally, the return value (if any) from that scope is available as the current topic within the phaser.


Runs at every unsuccessful block exit, as part of the LEAVE queue (shares the same order of execution).


Asserts a precondition at every block entry. Runs before the ENTER phase.

PRE phasers fire off before any ENTER or FIRST.

The exceptions thrown by failing PRE and POST phasers cannot be caught by a CATCH in the same block, which implies that POST phaser are not run if a PRE phaser fails.


Asserts a postcondition at every block entry. Runs after the LEAVE phase.

For phasers such as KEEP and POST that are run when exiting a scope normally, the return value (if any) from that scope is available as the current topic within the phaser.

The POST block can be defined in one of two ways. Either the corresponding POST is defined as a separate phaser, in which case PRE and POST share no lexical scope. Alternately, any PRE phaser may define its corresponding POST as an embedded phaser block that closes over the lexical scope of the PRE.

If a POST fails or any kind of LEAVE block throws an exception while the stack is unwinding, the unwinding continues and collects exceptions to be handled. When the unwinding is completed all new exceptions are thrown from that point.

The exceptions thrown by failing PRE and POST phasers cannot be caught by a CATCH in the same block, which implies that POST phaser are not run if a PRE phaser fails.

Loop Phasers

FIRST, NEXT, and LAST are meaningful only within the lexical scope of a loop, and may occur only at the top level of such a loop block.


Runs at loop initialization, before ENTER.


Runs when loop is continued (either through next or because you got to the bottom of the loop and are looping back around), before LEAVE.

A NEXT executes only if the end of the loop block is reached normally, or an explicit next is executed. In distinction to LEAVE phasers, a NEXT phaser is not executed if the loop block is exited via any exception other than the control exception thrown by next. In particular, a last bypasses evaluation of NEXT phasers.


Runs when loop is aborted (either through last, or return, or because you got to the bottom of the loop and are done), after LEAVE.

Exception Handling Phasers


Runs when an exception is raised by the current block, before the LEAVE phase.


Runs when a control exception is raised by the current block, before the LEAVE phase. It is raised by return, fail, redo, next, last, take, warn, proceed and succeed.

say elems gather {
        when CX::Warn { say "WARNING!!! $_"; .resume }
        when CX::Take { say "Don't take my stuff"; .resume }
    warn 'people take stuff here';
    take 'keys';
# WARNING!!! people take stuff here
# Don't take my stuff
# 0
# NYI # =head1 Object Phasers # # =head2 X<COMPOSE|Phasers, COMPOSE> # # Runs when a role is composed into a class.

Asynchronous Phasers


Runs when a Supply finishes with a call to done or when a supply block exits normally. It runs completely after the whenever block it is placed within finishes.

This phaser reuses the name LAST, but works differently from the LAST loop phaser. This phaser is similar to setting the done routine while tapping a supply with tap.


Runs when a Supply terminates early with an exception. It runs after the whenever block it is placed within finishes.

This phaser is similar to setting the quit routine while tapping a Supply with tap.

DOC phasers


The phasers BEGIN, CHECK and INIT are run only in documentation mode when prefixed with the DOC keyword. The compiler is in documentation when run with --doc.

DOC INIT { say 'init'  }  # prints 'init' at initialization time when in documentation mode.

37 Perl 6 Pod

An easy-to-use markup language

Perl 6 Pod is an easy-to-use markup language. Pod can be used for writing language documentation, for documenting programs and modules, as well as for other types of document composition.

Every Pod 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 Perl 6 Pod document 
 =end pod 

Block Structure

A Pod document may consist of multiple Pod 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, ...)
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]
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, $2, ...' are values of type String, Int, Number, or Boolean.

Strings are delimited by single or double quotes. Whitespace is insignificant outside of strings. Hash keys need not be quote-delimited unless they contain significant whitespace.

All option keys and values must, of course, be constants since Pod 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. (NOTE: This feature is not yet implemented. All configuration information currently must be provided on the same line as the =begin marker line.)

Paragraph blocks

Paragraph blocks begin by a =for marker and end by the next Pod directive or the first blank line. The =for marker is followed by the typename of the block.

=for head1 
 Top Level Heading 

Abbreviated blocks

Abbreviated blocks begin by an '=' sign, which is followed immediately by the typename of the block. The block ends at the next Pod 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 bracket. If followed by a space, the block is terminated by the end of line; if followed by one or more opening brackets, the block is terminated by the matching sequence of closing brackets.

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

The WHY method can be used on these classes, roles, subroutines etc. to return the attached Pod 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.␤» 

Block types

Pod 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

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

Would be rendered this way:

Happy When you're not blue.

Blue When you're not happy.

Which, for the time being, might be a simple HTML paragraph, but might change in the future.

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

Pod comments

Pod comments are comments that Pod renderers ignore.

Comments are useful for meta-documentation (documenting the documentation):

=comment Add more here about the algorithm 

For multi-line comments use a delimited 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 Pod formatting codes consist of a single capital letter followed immediately by a set of angle brackets.

Formatting codes may nest other formatting codes.


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

Perl 6 homepage L<> 
 L<Perl 6 homepage|> 

Perl 6 homepage

Perl 6 homepage

To create a link to a section in the same document:

Comments L<#Comments> 

Comments #Comments


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> 

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 Pod document, enclose them in E< >

E< > can enclose a number, that number 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.

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

Using the terminal run the following command:

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

Using the terminal run the following command:

perl6 --doc=Markdown input.pod6 > 


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 Pod 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 Pod rendered as a man page.

Accessing Pod

In order to access Pod documentation from within a Perl 6 program it is required to use the special = twigil, as documented in the variables section.

The = twigil provides the introspection over the Pod structure, providing a Pod::Block tree root from which it is possible to access the whole structure of the Pod document.

As an example, the following piece of code introspects its own Pod documentation:

=begin pod 
 =head1 This is an 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: => 1, config => {}, contents => [ => {}, contents => ["This is an head1 title"])]); => {}, contents => ["This is a paragraph."]); => 2, config => {}, contents => [ => {}, contents => ["Subsection"])]); => {}, contents => ["Here some text for the subsection."]); 

38 Pragmas

Special modules for special use

In Perl 6, pragmas are core modules used to either identify a specific version of Perl 6 to be used or to modify its normal behavior in some way. They are "use"ed in your code just as normal modules:

use v6.c; 

Following is a list of pragmas with a short description of each pragma's purpose or a link to more details about its use. (Note: Pragmas marked "[NYI]" are not yet implemented, and those marked "[TBD]" are to be defined later.)

The following should be a table but formatting in tables is not yet rendered properly.

This pragma is not currently part of any Perl 6 specification, but is present in Rakudo as a synonym to use nqp (see below).

A lexical pragma that makes Failures returned from routines fatal. For example, prefix + on a Str coerces it to Numeric, but will return a Failure if the string contains non-numeric characters. Saving that Failure in a variable prevents it from being sunk, and so the first code block below reaches the say $x.^name; line and prints Failure in output.

In the second block, the use fatal pragma is enabled, so the say line is never reached because the Exception contained in the Failure returned from prefix + gets thrown and the CATCH block gets run, printing the Caught... line. Note that both blocks are the same program and use fatal only affects the lexical block it was used in:

    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Failure␤»

    use fatal;
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Caught X::Str::Numeric␤»

Inside of a try blocks, the fatal pragma is enabled by default, and you can disable it with no fatal:

try {
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Caught X::Str::Numeric␤»

try {
    no fatal;
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Failure␤»

Set the value of the $?NL constant in the scope it is called. Possible values are :lf (which is the default, indicating Line Feed), :crlf (indicating Carriage Return, Line Feed) and :cr (indicating Carriage Return).

Use at your own risk.

This is a Rakudo-specific pragma. With it, Rakudo provides access to the nqp opcodes in a top level namespace:

use nqp;
nqp::say("hello world");

This uses the underlying nqp say opcode instead of the Perl 6 routine. This pragma may make your code rely on a particular version of nqp, and since that code is not part of the Perl 6 specification, it's not guaranteed to be stable. You may find a large number of usages in the Rakudo core, which are used to make the core functionality as fast as possible. Future optimizations in the code generation of Rakudo may obsolete these usages.

The default allows precompilation of source code, specifically if used in a module. If for whatever reason you do not want the code (of your module) to be precompiled, you can use no precompilation. This will prevent the entire compilation unit (usually a file) from being precompiled.

strict is the default behavior, and requires that you declare variables before using them. You can relax this restriction with no.

no strict; $x = 42; # OK 

When use trace is activated, any line of code executing will be written to STDERR. You can use no trace to switch off the feature, so this only happens for certain sections of code.

Lexically controls whether compile-time warnings generated by the compiler get shown. Enabled by default.

$ perl6 -e 'say :foo<>.Pair' 
 Potential difficulties: 
   Pair with <> really means an empty list, not null string; use :foo('') to represent the null string, 
     or :foo() to represent the empty list more accurately 
   at -e:1 
   ------> say :foo<>⏏.Pair 
 foo => Nil 
 $ perl6 -e 'no worries; say :foo<>.Pair' 
 foo => Nil 

The following pragma's have been discussed in the past, but will most likely never see any functionality implemented for them:


39 Perl 6 from Python - 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!". put in Perl 6 is the equivalent of print in Python. Like Python 2, parentheses are optional. A return 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 say, which behaves similarly, but will call the gist method of its argument.

Perl 6

my $hello; ...;
say "Hello, world!";  # also prints "Hello, world"
say $hello;           # 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, bracket, or curly brace, the statement continues across lines, until the matching 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;
if True { say 1 + 2 }


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 in expressions in conditionals, as shown above.


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

foo = 12 
 bar = 19 

In Perl 6, my declares a lexical variable. A variable can be initialized with =. i.e. these can be written as two statements or one.

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). Immutable variables can be sigil-less, if they are declared with a \.


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). 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 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. i.e. 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 make list comprehensions.


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

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, "instance variables", aka attributes in Perl 6:


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

Perl 6:

class Dog {
    has $.name;

Constructors by default take named arguments in Perl 6, and use the method new.


d = Dog('Fido') 
 e = Dog('Buddy') 

Perl 6

class Dog {}; ...;
my $d =<Fido>);
my $e =<Buddy>);
say $;
say $;

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):  = name           # instance attribute 
 d = Dog('Fido') 
 e = Dog('Buddy') 
 print d.kind 
 print e.kind 

Perl 6:

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

my $d =<Fido>);
my $e =<Buddy>);
say $d.kind;
say $e.kind;
say $;
say $;

To mutate attributes, in Perl 6 you"ll want to use is rw:


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

Perl 6:

class Dog {
    has $.name is rw;
my $d =;
$ = '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 =;

Multiple inheritance is possible by using is multiple times, or with also.


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


See the prompt function.

40 Quoting Constructs

Writing strings, word lists, and regexes in Perl 6

The Q Lang

Strings are usually represented in Perl 6 code using some form of quoting construct. The most minimalistic of these is Q, usable via the shortcut 「…」, or via Q followed by any pair of delimiters surrounding your text. Most of the time, though, the most you'll need is '…' or "…", described in more detail in the following sections.

Literal strings: Q

Q[ A literal string ] 
  More plainly.  
 Q ^ Almost any non-word character can be a delimiter! ^ 
 Q 「「 Delimiters can be repeated/nested if they are adjacent. 」」 

Delimiters can be nested, but in the plain Q form, backslash escapes aren't allowed. In other words, basic Q strings are as literal as possible.

Some delimiters are not allowed immediately after Q, q, or qq. Any characters that are allowed in identifiers are not allowed to be used, since in such a case, the quoting construct together with such characters are interpreted as an identifier. In addition, ( ) is not allowed because that is interpreted as a function call. If you sti