Day 12 – Smart matching

Remember the https://perl6advent.wordpress.com/2010/12/04/the-sequence-operator/ sequence operator? As the last argument it takes a limit, which makes the sequence generation stop. For example:

    1, 2, 4 ... 32;         # 1 2 4 8 16 32
    1, 2, 4 ... * > 10;     # 1 2 4 8 16

You can see that in the first case, numerical equality is used. The second is a bit more interesting: * > 10 is internally rewritten into a closure like -> $x { $x > 10 } (through currying).

The sequence operator then does some magic comparison, depending on the type of the matcher. This comparison is called "smartmatching", and is a concept that reappears in many places in Perl 6. Examples:

    # after the 'when' keyword:
    given $age {
        when 100    { say "congratulations!"      }
        when * < 18 { say "You're not of age yet" }
    }
    # after 'where':
    subset Even of Int where * %% 2;
    # with an explicit smartmatch operator:
    if $input ~~ m/^\d+$/ {
        say "$input is an integer";
    }
    # arguments to grep(), first() etc.:
    my @even = @numbers.grep: Even;

On the right-hand side of the ~~ operator, and after when and where, the value to be matched against is set to the topic variable $_. This allows us to use constructs that operate on $_, like regexes created with m/.../ and .method_call.

Here is what the smart match operator does with some matchers on the right-hand side:

    # is it of type Str?
    $foo ~~ Str
    # is it equal to 6?
    $foo ~~ 6
    # or is it "bar"?
    $foo ~~ "bar"
    # does it match some pattern?
    $foo ~~ / \w+ '-' \d+ /
    # Is it between 15 and 25?
    $foo ~~ (15..25)
    # call a closure
    $foo ~~ -> $x { say 'ok' if 5 < $x < 25 }
    # is it an array of 6 elems in which every odd element is 1?
    $foo ~~ [1, *, 1, *, 1, *]

The full table for smart matching behavior can be found at
http://perlcabal.org/syn/S03.html#Smart_matching.

Notice how, unlike in Perl 5, in Perl 6 smartmatching is the only syntactic way to match a regex, it has no special operator. Also, while most smart matching cases return a Bool, matching against a regex returns a Match object – which behaves appropriately in boolean context too.

You have probably started wondering: a’right, that for built-in types, how do I use it in my own classes? You need to write a special ACCEPTS method for it. Say we have our good, old class Point:


    class Point {
        has $.x;
        has $.y;
        method ACCEPTS(Positional $p2) {
            return $.x == $p2[0] and $.y == $p2[1]
        }
    }

Everything clear? Let’s see how it works:

    my $a = Point.new(x => 7, y => 9);
    say [3, 5] ~~ $a; # Bool::False
    say (7, 9) ~~ $a; # Bool::True

Perl 6 can now do exactly what you mean, even with your own classes.

Day 9 – The module ecosystem

The Perl 6 module database on http://modules.perl6.org is certainly not CPAN yet, but there are still a number of things worth using, or at least knowing about. There’s no "standard" module installer for Perl 6, like there’s a cpan shell for Perl 5, but the most commonly used and most often working is neutro. It’s a simple script fetching, building, and installing modules from the ecosystem, resolving dependencies and checking if the tests are passing: not much more we need. Let’s see how to install something interesting with it, say JSON::Tiny, a JSON parser.

First, we need to get neutro. We will assume you use git to obtain it; notice that git is also obligatory to download modules (all of them live on github currently).

    git clone git://github.com/tadzik/neutro.git
    cd neutro
    PERL6LIB=tmplib bin/neutro .

That will download neutro and bootstrap it using the supplied libs. What we end up is the module installer itself, and the File::Tools and Module::Tools distributions. Make sure ~/.perl6/bin is in your PATH enviroment variable, so you will be able to run neutro without specifying its exact location. You are now able to install modules as simply as with cpanminus:

    neutro json
    neutro perl6-Term-ANSIColor
    neutro perl6-lwp-simple

You may notice module names are not similar to what you may be used to from Perl 5. They’re not standarized, they’re just the names of a git repos they live in. To make sure what you are looking for, consult the
list:

    neutro update # fetch the fresh list of modules
    neutro list

Modules will be installed to ~/.perl6/lib, which is in the default search path of Rakudo, so you don’t really need to set PERL6LIB yourself:

    perl6 -e 'use Term::ANSIColor; say colored("Hello blue world!", "blue")'

You probably just can’t wait to write your first module and make it available for the whole world. There’s no CPAN where you can send your packages; the usual workflow is creating a repository on Github and adding it to the projects.list file in the ecosystem. You don’t need to have a direct access to the repo to get your module published. You can either send a pull request for your forked ecosystem repo, send a patch, or just ask some of the commiters or people on the #perl6 channel of Freenode.

How to write a module, what tools to use? If you’re interested, look into the guide.

Happy hacking!

Day 1 – Reaching the Stars

Coming from the Perl 5 world, or from some other background, you may think of the programming language and its implementation as the one thing, or at least things very strongly tied to each other. Perl 6 is different. The “official” part is the specification (the Synopses) and the tests suite. Perl 6 encourages multiple implementations. Any implementation passing the official test suite and fulfiling the Synopses may call itself “a Perl 6 implementation”. While there is still no such implementation, there is alredy a few compilers in the ecosystem.

Rakudo is targetting the Parrot virtual machine, and it’s the most complete implementation so far. Niecza is targetting .NET and is aiming to study performance issues. There is also Yapsi, whose “author has claimed that it’s official for over half a year now, and not once been contradicted” :) We will be using Rakudo for our examples as it is the most complete implementation around and has the largest ecosystem built around it.

Like with Perl 6, there is no “one Rakudo to rule them all”. The Rakudo development team has decided to keep the compiler separate from the distribution. That means the Rakudo release is not a ready-to-use Perl 6 tarball, with modules, documentation and a virtual machine. That’s what Rakudo Star is. First released about half a year ago, Rakudo Star contains the toolbox with everything needed for Perl 6 hacking: a release of Parrot virtual machine, the Perl 6 Book, a bunch of modules and the Rakudo itself.

Getting Rakudo Star

The Rakudo Star tarballs are located at https://github.com/rakudo/star/downloads. Go get one suitable for your system and become ready for Christmas… again!