Perl5::Differences(3)

NAME
Perl6::Perl5::Differences -- Differences between Perl 5 and Perl 6

DESCRIPTION
This document is intended to be used by Perl 5 programmers who are new to Perl 6 and just want a quick overview of the main differences. More detail on everything can be found in the language reference, which have been linked to throughout.

This list is currently known to be incomplete.

Bits and Pieces

  Sigils
Where you used to say:

    my @fruits = ("apple", "pear", "banana");
    print $fruit[0], "\n";

You would now say:

    my @fruits = "apple", "pear", "banana";
    say @fruit[0];

Or even use the "<>" operator, which replaces "qw()":

    my @fruits = <apple pear banana>;

Note that the sigil for fetching a single element has changed from "$" to "@"; perhaps a better way to think of it is that the sigil of a variable is now a part of its name, so it never changes in subscripting.

The same applies to hashes:

    say "There are %days{'February'} days in February";

Again, there is a shorter form:

    say "There are %days<February> days in February";

For details, see "Names and Variables" in S02.

  Global variables have a twigil
Yes, a twigil. It's the second character in the variable name. For globals, it's a "*"; for contextual variables, it's "+".

    Was:    $ENV{FOO}
    Now:    %*ENV<FOO>
     Or:    $+FOO # might be overridden, but falls back to %*ENV

For details, see "Names and Variables" in S02.

  New ways of referring to array and hash elements
Number of elements in an array:

    Was:    $#array+1 or scalar(@array)
    Now:    @array.elems

Index of last element in an array:

    Was:    $#array
    Now:    @array.end

Therefore, last element in an array:

    Was:    $array[$#array]
    Now:    @array[@array.end]
            @array[*-1]              # beware of the "whatever"-star

For details, see "Built-In Data Types" in S02

  The double-underscore keywords are gone
    Old                 New
    ---                 ---
    __LINE__            $?LINE
    __FILE__            $?FILE
    __PACKAGE__         $?PACKAGE
    __END__             =begin END
    __DATA__            =begin DATA

See "double-underscore forms are going away" in S02 for details. The "?" twigil refers to data that is known at compile time.

  Context
There are still three main contexts, void, item (formerly scalar) and list. Aditionally there are more specialized contexts, and operators that force that context.

    my @array = 1, 2, 3;

    # generic item context
    my $a = @array; say $a.WHAT;    # prints Array

    # string context
    say ~@array;                    # "1 2 3"

    # numeric context
    say +@array;                    # 3

    # boolean context
    my $is_nonempty = ?@array;

Operators
A comprehensive list of operator changes is documented at "Changes to Perl 5 operators" in S03 and "New operators" in S03.

Some highlights:

  "qw()" changes; new interpolating form
    Was:    qw(foo)
    Now:    <foo>

    Was:    ("foo", (split /s+/, $bar), "bat")
    Now:    <<foo $bar bat>>

Quoting operators now have modifiers that can be used with them (much like regexes and substitutions in Perl 5), and you can even define your own quoting operators. See S03 for details.

Note that "()" as a subscript is now a sub call, so instead of "qw(a b)" you would write "qw<a b>" or "qw[a b]" (if you don't like plain "<a b>"), that is).

  Other important operator changes
String concatenation is now done with "~".

Regex match is done with the smart match operator "~~", the perl 5 match operator "=~" is gone.

    if "abc" ~~ m/a/ { ... }

"|" and "&" as infix operators now construct junctions. The binary AND and binary OR operators are split into string and numeric operators, that is "~&" is binary string AND, "+&" is binary numeric AND, "~|" is binary string OR etc.

Parenthesis don't construct lists any more, they merely group. Lists are constructed with the comma operator. It has looser precedence than the list assignment operator, which allows you to write lists on the right hand side wihtout parens:

    my @list = 1, 2, 3;     # @list really has three elements

The arrow operator "->" for dereferncing is gone. Since (nearly) everything is a reference, you can directly use the apropriate pair of parenthesis for either indexing or method calls:

    my $lol = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    say $lol[1][0];         # 4

    my $s = sub { say "hi" };
    $s();
    # or
    $s.();
    $lol.[1][0]

Blocks and Statements
See S04 for the full specification of blocks and statements in Perl6.

  You don't need parens on control structure conditions
    Was:    if ($a < $b) { ... }
    Now:    if  $a < $b  { ... }

Likewise for "while", "for", etc. If you insist on using parens, make sure there's a space after the "if", otherwise it's a sub call.

  eval {} is now try {}
Using "eval" on a block is now replaced with "try".

    Was:  eval {
            # ...
          };
          if ($@) {
            warn "oops: $@";
          }
    Now:  try  {
             # ...
             CATCH { warn "oops: $!" }
          }

CATCH provides more flexiblity in handling errors. See "Exception_handlers" in S04 for details.

  foreach becomes for
    Was:    foreach (@whatever) { ... }
    Now:    for @whatever       { ... }

Also, the way of assigning to something other than $_ has changed:

    Was:    foreach my $x (@whatever) { ... }
    Now:    for @whatever -> $x       { ... }

This can be extended to take more than one element at a time:

    Was:    while (my($age, $sex, $location) = splice @whatever, 0, 3) { ... }
    Now:    for @whatever -> $age, $sex, $location { ... }

(Except the "for" version does not destroy the array.)

See "The for statement" in S04 and "each" in S29 for details.

  for becomes loop
    Was:    for  ($i=0; $i<10; $i++) { ... }
    Now:    loop ($i=0; $i<10; $i++) { ... }

"loop" can also be used for infinite loops:

    Was:    while (1) { ... }
    Now:    loop { ... }

Regexes and Rules
Here's a simple translation of a Perl5 regular expression to Perl6:

    Was:    $str =~ m/^\d{2,5}\s/i
    Now:    $str ~~ m:P5:i/^\d{2,5}\s/

The ":P5" modifier is there because the standard Perl6 syntax is rather different, and 'P5' notes a Perl5 compatibility syntax. For a substitution:

    Was:    $str =~ s/(a)/$1/e;
    Now:    $str ~~ s:P5/(a)/{$0}/;

Notice that $1 starts at $0 now, and "/e" is gone in favor of the embedded closure notation.

For the full specification, see S05. See also:

The related Apocalypse, which justifies the changes:

  http://dev.perl.org/perl6/doc/design/apo/A05.html

And the related Exegesis, which explains it more detail:

  http://dev.perl.org/perl6/doc/design/exe/E05.html

Subroutines

Formats

  Formats have been replaced with forms.
For details see :

<http://dev.perl.org/perl6/doc/design/apo/A07.html> Format Apocalypse

<http://dev.perl.org/perl6/doc/design/exe/E07.html> Format Exegesis

Packages

Modules

Objects
Perl 6 has a "real" object system, with key words for classes, methods and attributes. Public attributes have the "." twigil, private ones the "!" twigil.

    class YourClass {
        has $!private;
        has @.public;

        # and with write accessor
        has $.stuff is rw;

        method do_something {
            if self.can('bark') {
                say "Something doggy";
            }
        }
    }

  Method invocation changes from -> to .
    Was:    $object->method
    Now:    $object.method

  Using code references in dynamic method calls is gone.
  Was: $self.$coderef()
  Now: $coderef(self:)

Overloading
Since both builtin functions and operators are multi subs and methods, changing their behaviour for particular types is a simple as adding the appropriate multi subs and methods. If you want these to be globally available, you have to but them into the "GLOBAL" namespace, which is indicated by an asterisk.

    multi sub *uc(TurkishStr $str) { ... }

    # "overload" the string concatenation:
    multi sub infix:<~>(TurkishStr $us, TurkishStr $them) { ... }

If you want to offer a type cast to a particular type, just provide a method with the same name as the type you want to cast to.

    sub needs_bar(Bar $x) { ... }
    class Foo {
        ...
        # coercion to type Bar:
        method Bar { ... }
    }

    needs_bar(Foo.new);         # coerces to Bar

  Offering Hash and List semantics
If you want to write a class whose objects can be assigned to a variable with the "@" sigil, you have to implement the "Positional" roles. Likewise for the "%" sigil you need to do the "Associative" role. The "&" sigil implies "Callable".

The roles provides the operators "postcircumfix:<[ ]>" (Positional; for array indexing), "postcircumfix:<{ }>" (Associative) and "postcircumfix:<()>" (Callable). The are technically just methods with a fancy syntax. You should override these to provide meaningful semantics.

    class OrderedHash does Associative {
        multi method postcircumfix:<{ }>(Int $index) {
            # code for accessing single hash elements here
        }
        multi method postcircumfix:<{ }>(*@@slice) {
            # code for accessing hash slices here
        }
        ...
    }

    my %orderedHash = OrderedHash.new();
    say %orderedHash{'a'};

See S13 for all the gory details.

  Chaining file test operators has changed
    Was: if (-r $file && -x _) {...}
    Now: if $file ~~ :r & :x  {...}

For details, see "Changes to Perl 5 operators"/"The filetest operators now return a result that is both a boolean" in S03

Documentation
You now use <em>kwid</em> for documentation instead of POD. Kwid is a wiki-like syntax that is easy to write, and pleasant to read directly.

Here is a side-by-side comparison of some of the major features of Pod and Kwid:

     =head1 Big Thing                    = Big Thing

     =head4 Small Thing                  ==== Small Thing

     A paragraph of                      A paragraph of
     plain text.                         plain text.

         # verbatim                          # verbatim
         sub v {                             sub v {
             shift;                              shift;
         }                                   }

     =item * foo                         * foo
     =item * bar                         * bar
     =item2 N<> barber                   ++ barber
     =item2 N<> bard                     ++ bard

     Something B<strong>!                Something *strong*!

     Something I<emphatic>!              Something /emphatic/!

     Some code C<E = M * C ^ 2>!         Some code `E = M * C ^ 2`!

     Some V<B<escaped>> markup           Some \*escaped\* markup

     =begin Section_type                 .Section_type

     =end Section_type                   !Section_type

     =for Section_type                   :Section_type

See S26 for details.

Builtin Functions
A number of builtins have been removed. For details, see:

"Obsolete" in S29

  References are gone (or: everything is a reference)
"Capture" objects fill the ecological niche of references in Perl 6. You can think of them as "fat" references, that is, references that can capture not only the current identity of a single object, but also the relative identities of several related objects. Conversely, you can think of Perl 5 references as a degenerate form of "Capture" when you want to refer only to a single item.

  Was: ref $foo eq 'HASH'
  Now: $foo ~~ Hash

  Was: @new = (ref $old eq 'ARRAY' ) ? @$old : ($old);
  Now: @new = @$old;

  Was: %h = ( k => \@a );
  Now: %h = ( k => @a );

To pass an argument to modify by reference:

  Was: sub foo {...};        foo(\$bar)
  Now: sub foo ($bar is rw); foo($bar)

The "obsolete" reference above has the details. Also, look for Capture under "Names_and_Variables" in S02, or at the Capture FAQ, Perl6::FAQ::Capture.

  say()
This is a version of "print" that auto-appends a newline:

    Was:    print "Hello, world!\n";
    Now:    say   "Hello, world!";

Since you want to do that so often anyway, it seemed like a handy thing to make part of the language.

  wantarray()
"wantarray" is superseeded by "want.list". Also available are "want.item" and "want.count", the latter gives the number of expected values, if applicable.

In general you are encouraged to return objects that do the right thing in each possible context instead of asking for your context explicitly.

Unfiled

  Hash elements no longer auto-quote
Hash elements no longer auto-quote:

    Was:    $days{February}
    Now:    %days{'February'}
    Or:     %days{"February"}
    Or:     %days<February>
    Or:     %days<<February>>

The curly-bracket forms still work, but curly-brackets are more distinctly block-related now, so in fact what you've got there is a block that returns the value "February". The "<"> and "<<">> forms are in fact just quoting mechanisms (see below).

  Built-in functions are now methods
Most (all?) built-in functions are now methods of built-in classes such as "String", "Array", etc.

    Was:    my $len = length($string);
    Now:    my $len = $string.chars;

    Was:    print sort(@array);
    Now:    print @array.sort;
            @array.sort.print;

You can still say "sort(@array)" if you prefer the non-OO idiom.

AUTHORS
Kirrily "Skud" Robert, <skud@cpan.org>, Mark Stosberg, Moritz Lenz, Trey Harris