## Archive for the ‘2009’ Category

### Day 5: Metaoperators

December 5, 2009

In the Day 4 box, we saw an interesting implementation for the factorial function:

```    sub fac(Int \$n) {
[*] 1..\$n
}
```

Okay, so how does that work? Opening up today’s Advent box provides some answers!

Perl 6 has a number of different “meta operators” that modify the existing operators to perform more powerful functions.

The square brackets about are an example of the “reduce metaoperator”; they cause an infix operator to become a list operator that acts as though the infix was placed between each pair of elements. For example, the expression

```    [+]  1, \$a, 5, \$b
```

is essentially the same as writing

```    1 + \$a + 5 + \$b
```

This gives us a handy mechanism to “sum all elements in a list”:

```    \$sum = [+] @a;            # sum all elements of @a
```

Most of the infix operators (including user-defined operators) can be placed inside of square brackets to turn them into reductions:

```    \$prod = [*] @a;           # multiply all elements of @a

\$mean = ([+] @a) / @a;    # calculate mean of @a

\$sorted = [<=] @a;        # true if elements of @a are numerically sorted

\$min = [min] @a, @b;      # find the smallest element of @a and @b combined
```

So, in the factorial subroutine above, the expression `[*] 1..\$n` returns the product of multiplying all of 1 through \$n together.

Another useful metaoperator is the “hyper” operator. Placing `»`
and/or `«` (or the ASCII `>>` and `<<` equivalents) next to an operator makes it “hyper”, which causes it operate on elements of lists. For example, the following calculates `@c` as the pairwise addition of the elements in `@a` and `@b`:

```    @c = @a »+« @b;
```

In Perl 5, we’d generally write something like

```    for (\$i = 0; \$i < @a; \$i++) {
\$c[\$i] = \$a[\$i] + \$b[\$i];
}
```

which is quite a bit longer.

As with the square brackets above, we can use hyper on a variety of operators, including user-defined operators:

```    # increment all elements of @xyz
@xyz»++

# each element of @x is the smaller of @a and @b
@x = @a »min« @b;
```

We can also flip the angles to enable a scalar to act like an array:

```    # multiply each element of @a by 3.5
@b = @a »*» 3.5;

# multiply each element of @x by \$m and add \$b
@y = @x »*» \$m »+» \$b;

# invert all elements of @x
@inv = 1 «/« @x;

# concatenate @last, @first to produce @full
@full = (@last »~» ', ') »~« @first;
```

Of course, reductions and hyper operators can be combined in expressions:

```    # calculate the sum of squares of @x
\$sumsq = [+] ( @x »**» 2);
```

There are many other metaoperators available, including `X` (cross), `R` (reverse), `S` (sequential). In fact, the “in-place” operators such as `+=`, `*=`, `~=`, are just meta forms created by suffixing an operator with an equals sign:

```    \$a += 5;      # same as \$a = \$a + 5;
\$b //= 7;     # same as \$b = \$b // 7;
\$c min= \$d;   # same as \$c = \$c min \$d;
```

### Day 4: Testing

December 4, 2009

Perl authors have a long tradition of shipping test cases with their modules, and in Perl 6 we plan to continue with that nice tradition.

And testing is very easy. The traditional perlish way is to print data in the Test Anything Protocol. But you don’t have to do that yourself, you can use a module for that.

Assume you have written a nice factorial function

``` sub fac(Int \$n) {
[*] 1..\$n
}```

Currently it doesn’t matter for us how that function works – we want to find out if it does. So let’s test it:

``` use v6;

sub fac(Int \$n) {
[*] 1..\$n
}

use Test;
plan 6;

is fac(0), 1,  'fac(0) works';
is fac(1), 1,  'fac(1) works';
is fac(2), 2,  'fac(2) works';
is fac(3), 6,  'fac(3) works';
is fac(4), 24, 'fac(4) works';

dies_ok { fac('oh noes i am a string') }, 'Can only call it with ints';```

And let’s run it:

``` \$ perl6 fac-test.pl
1..6
ok 1 - fac(0) works
ok 2 - fac(1) works
ok 3 - fac(2) works
ok 4 - fac(3) works
ok 5 - fac(4) works
ok 6 - Can only call it with ints```

In detail: `use Test;` loads the testing module, `plan 6;` declares that we plan to run six tests. Then five lines of the pattern `is \$got, \$expected, \$description` follow. `is()` does string comparison, but since integers always stringify the same way, that’s fine.

Finally with `dies_ok { \$some_code }, \$description` we test that calling the function with a non-integer argument is a fatal error.

The output contains the test plan `1..6`, followed by one line for each test. That starts with `ok` (or `not ok` if the test failed), the test number, space, dash, space and test description.

If you run more tests, you don’t want to look through every test output carefully, but you want a summary. The prove command from Perl 5 gives you such a summary:

``` prove --exec perl6 fac-test.pl
fac-test.pl .. ok
All tests successful.
Files=1, Tests=6, 11 wallclock secs ( 0.02 usr  0.00 sys + 10.26 cusr  0.17 csys = 10.45 CPU)
Result: PASS```

You can also put all your test files in a directory, let’s call it `t/`, and run prove recursively on all `.t` files in that dir:

` prove --exec perl6 -r t`

Putting that line in your Makefile is also nice, so that you can just type
`make test` to run the tests.

### Day 3: static types and multi subs

December 3, 2009

The third box is ready for opening this Advent. Inside…well, looks like two gifts! Inside the box are static types and multi subs.

In Perl 5, `\$scalar` variables could contain either references or values. Specifically, the values could be anything. They could be integers, strings, numbers, dates: you name it. This offers some flexibility, but at the cost of clarity.

Perl 6 is going to change that with its static types. If you want a particular variable, you place the type name in between `my` and `\$variable-type`. As an example, to set up a variable to be an Int, one can do this:

`my Int \$days = 24;`

Other static types are as follows:

• `my Str \$phrase = "Hello World";`
• `my Num \$pi = 3.141e0;`
• `my Rat \$other_pi = 22/7;`

If you still want the old behavior of the variables, you can either choose not to declare a static type or use `Any` instead.

This gift can easily go hand in hand with the second gift inside the box today: multi subs. What exactly are multi subs? In short, multi subs allow for the overloading of sub names. While multi subs can also do so much more, those are gifts for another day. For now, here are some subs that can be useful:

``````
multi sub identify(Int \$x) {
return "\$x is an integer.";
}

multi sub identify(Str \$x) {
return qq<"\$x" is a string.>;
}

multi sub identify(Int \$x, Str \$y) {
return "You have an integer \$x, and a string \"\$y\".";
}

multi sub identify(Str \$x, Int \$y) {
return "You have a string \"\$x\", and an integer \$y.";
}

multi sub identify(Int \$x, Int \$y) {
return "You have two integers \$x and \$y.";
}

multi sub identify(Str \$x, Str \$y) {
return "You have two strings \"\$x\" and \"\$y\".";
}

say identify(42);
say identify("This rules!");
say identify(42, "This rules!");
say identify("This rules!", 42);
say identify("This rules!", "I agree!");
say identify(42, 24);
``````

There is plenty to take advantage of with these two gifts. Try playing around with them, and keep coming back to our tree for more gifts that can use these features to their fullest extent. ☺

### Day 2: The beauty of formatting

December 2, 2009

Unwrapping the second gift brought to you by Perl 6 this Advent, we find… a method named `.fmt`.

If you’re familiar with `sprintf`, you’ll feel right at home with `.fmt`. If you haven’t heard about `sprintf` before, or if you’ve heard of it but are a bit fuzzy on the details, you might want to skim the perldoc page. Don’t drown in it, though; it’s longish. Just savour it.

Back to `.fmt`, `sprintf`‘s spunky little sister. Here are a few ways to use `.fmt` to format strings and integers.

```  say 42.fmt('%+d')                # '+42'
say 42.fmt('%4d')                # '  42'
say 42.fmt('%04d')               # '0042'
say :16<1337f00d>.fmt('%X')      # '1337F00D'```

All this is good and well, but not really more than a shorter method form of `sprintf`. Big deal, right?

What I haven’t told you yet is that `.fmt` is overloaded, and works differently on arrays (or more precisely, lists):

```  say <huey dewey louie>.fmt       # 'huey dewey louie'
say <10 11 12>.fmt('%x')         # 'a b c'
say <1 2 3>.fmt('%02d', '; ')    # '01; 02; 03'```

Similarly, it’s overridden on hashes (or rather, mappings):

```  say { foo => 1, bar => 2 }.fmt   # 'foo     1
#  bar     2'```
```  say { Apples => 5, Oranges => 10 }.fmt('%s cost %d euros')
# 'Apples cost 5 euros
#  Oranges cost 10 euros'```
```  say { huey => 1, dewey => 2, louie => 3 }.fmt('%s', ' -- ')
# 'huey -- dewey -- louie'```

The way hashing works may give your output a different order than the ones shown above. Oh, and there’s an overloaded `.fmt` for pairs as well, but it works analogously to the one for hashes.

`.fmt` is a useful little tool to have when you want to change some value, or an array or a hash of values, into to some given format. It’s like `sprintf`, but tailored to Do What You Mean for arrays and hashes, too.

There’s only one risk in all of this: Perl 6 might soil the reputation of the Perl family of languages by simply being too darn readable. In order to counter this risk, I leave a small parting gift in the form of a simple-but-dense Christmas tree printing Perl 6 one liner:

```  \$ perl6 -e 'say " "x 9-\$_,"#"x\$_*2-1 for 0..9,2 xx 3'

#
###
#####
#######
#########
###########
#############
###############
#################
###
###
###```
[*] If you are using Windows, remember you need to switch the quotes around
`c:\>perl6.exe -e "say ' 'x 9-\$_,'#'x\$_*2-1 for 0..9,2 xx 3"`

### Day 1: Getting Rakudo

December 1, 2009

There are many different partial implementations of Perl 6; at the moment, the most complete is Rakudo. There are a number of different ways to get it up and running, but if you have any interest in tracking or helping with the development, the best approach is to download directly from the source repositories and and build your own copy.

To do so, you will need Subversion (svn), git, Perl 5.8 or newer, a C compiler, and a make utility. On standard Linux-like systems (including OS X), you can build it like this:

```\$ git clone git://github.com/rakudo/rakudo.git
\$ cd rakudo
\$ perl Configure.pl --gen-parrot
\$ make
\$ make test
\$ make install```

Subversion is needed to run –gen-parrot — it actually uses svn to get the appropriate version of parrot and then compile it.  You will need to use the appropriate make command for your system.  (It’s generally `nmake` with MS Visual C++, I believe.)

For current Rakudo, `make install` doesn’t install into your path, it merely preps the system so that you can run the perl6 executable (created in the rakudo directory) from any other directory on your system. Once you have it going, you can easily play around with Perl 6 by executing `perl6` with no arguments, putting you into a REPL environment where you can type commands and see what they do. This can be incredibly handy for trying to figure out how Perl 6 works. For instance,

```\$ ./perl6
> say "Hello world!";
Hello world!
> say (10/7).WHAT
Rat()
> say [+] (1..999).grep( { \$_ % 3 == 0 || \$_ % 5 == 0 } );
233168
```

The lines starting with \$ and > are what you type; the other lines are Rakudo’s response. The first example is a simple `say` statement. The second creates a rational number and asks `WHAT` its type is (`Rat`). The third takes the list of numbers from 1 to 999, filters out the ones not divisible by 3 or 5, sums them, and then says the result. (This is Project Euler Problem #1, thanks to draegtun for reminding me of it.) We’ll try to explain how these things work in a future post.

One last thing. If you have any difficulties getting Rakudo working, the #perl6 channel on irc.freenode.net is usually very helpful.