Perl 5 to Perl 6 guide - syntax

Syntactic differences between Perl 5 and Perl 6

perlsyn - Perl syntax


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


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

Free form

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

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

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

See Whitespace for details.


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


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

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

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

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

Truth and falsehood

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

Statement modifiers

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

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

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

Compound statements

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

Loop control

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

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

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

For loops

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

Foreach loops

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

Switch statements

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

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

The full details can be found here.


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

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

For what is planned for goto, see

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