Day 24 – Advent Ventures

Day 24 – Advent Ventures

Here at the end of megayears of human adventure,
we schedule a silent night to stop time,
once again awaiting the next advent
of the answer to our questionable venture.

    Are we there yet?

After a gigayear or so of slogging from slime to silicon
mercifully forgetting (most of) the unmerciful past,
and the scars left by unnatural nature upon our pedigree,
we now remember to remember the future once more.

    Are we there yet?

So in this month, 26 year-moments after the advent of Perl,
(including 13 year-eternities of precocious brat sisterhood)
our little family celebrates, 24 tales at a time,
its victories in the struggle to find our way home.

    Are we there yet, Daddy, are we there yet?

We follow after all those who wander but are not lost:
We follow Abraham, looking for a city because it isn't there yet;
We follow Strider, guarding the hobbits who will redistribute the future;
We follow Magi and wizard, scholar and explorer, saint and scientist.

    I wonder as I wander out under the sky...whether I'm lost yet...

But wise man or hobbit, we must all take that journey in the dark,
groping ahead for the path to better air and a little hope,
following the encapsulated starlight past monsters and chasms
out to a land where the weary can rest, and be healed of grief.

    "Wait, what do you mean, I can't go there?" —Gandalf

We must all wander in this desert for forty years,
burying the bones of naysayers and yaysayers alike,
so that their children can someday cross the Jordan
into a land flowing with milk and honey and fancy new phones!

    "Wait, what do you mean, I can't go there?" —Moses

We carry these old stories to the future,
cadences to chant over the confusion of the road,
backpacks full of epics, pockets stuffed with tales,
leaving our own litter of anecdotal evidence behind us.

    You haven't heard some of the good ones yet.

So kids, along with the old stories, pack a few new tools,
light but powerful tools that will help you and help you help us.
The lightest tools, the most powerful tools, are ideas,
so pack lots and lots of 'em. I'll wait here while you do.

    I'm here yet. Which means I'm not there yet. Hurry up!

Pick some good friends, and let some good friends pick you.
Take turns waiting patiently, running impatiently,
or walking hopefully, crawling hopelessly,
standing up yet again defiantly. Or woozily, that works too.

    Be the protagonist some of the time, yet not all of the time.

Trust your journey to provide you with new companions;
trust your new companions to provide you with your journey.
Be prepared to say your eternal hellos and temporary goodbyes.
(No one's ever ready for the temporary hellos and eternal goodbyes.)

    And I'm not sure I want to be there quite yet.

Enjoy the companions your journey gives today, for life is bittersweet.
Enjoy the bittersweet songs and the bittersweet beer.
Enjoy the bitter fights and sweet hugs.
And, yes, enjoy the resulting bruises, but not too much.

    Enjoy knowing that you're not there yet.

Welcome, my friends, to the here, and to the not-there-yet.
Welcome to the clan's quantum superposition of joy and grief and longing.
Welcome to our ongoing effort to steal more of that Promethean fire
that burns too fast yet never fast enough to fit the firepits of our lives.

    Are we getting warmer yet?

As they say, "Give a man a fire..." Hold that thought, some breaking news...
This just in: Fire from heaven is now free and open-sourced?! Well, huh...
Seems a blogger heard some angels singing popup advent adverts in the cloud?
Hmm...better do some fact checking...hang in there...tum tiddly tum...

    Darn flakey connection...almost there...

Well, hey, whaddya know?! The physicists figured it out.
The whole universe has just finished compiling without error...
Now they're looking for someone to debug the silly thing;
Hey, I know, I'll just use the Perl 6 test suite.

    [ you have thousands of problems...]

Did you say something?

    (louder) Does sanity test #1 pass yet? What's the output?

The road goes ever on and on,
Over the river and through the woods,
You take the high road, and I'll take the low road,
We're all bound for the Promised Land.

[TimToady gets blessed and starts directing the choir of Perl Pilgrims.]
We're marching to Zion,
Beautiful, beautiful Zion,
We're marching upward to Zion, that beautif—

    You can't go there.

Wait, what do you mean, I can't go there?

    Bugfix #1: kill all the bad poets.

Day 23 – Unary Sort

Day 23 – Unary Sort

Most languages or libraries that provide a generic sort routine allow you to specify a comparator, that is a callback that tells the sort routine how two given elements compare. Perl is no exception.

For example in Perl 5, which defaults to lexicographic ordering, you can request numeric sorting like this:

 use v5;
 my @sorted = sort { $a <=> $b } @values;

Perl 6 offers a similar option:

 use v6;
 my @sorted = sort { $^a <=> $^b }, @values;

The main difference is that the arguments are not passed through the global variables $a and $b, but rather as arguments to the comparator. The comparator can be anything callable, that is a named or anonymous sub or a block. The { $^a <=> $^b} syntax is not special to sort, I have just used placeholder variables to show the similarity with Perl 5. Other ways to write the same thing are:

 my @sorted = sort -> $a, $b { $a <=> $b }, @values;
 my @sorted = sort * <=> *, @values;
 my @sorted = sort &infix:«<=>», @values;

The first one is just another syntax for writing blocks, * <=> * use * to automatically curry an argument, and the final one directly refers to the routine that implements the <=> "space ship" operator (which does numeric comparison).

But Perl strives not only to make hard things possible, but also to make simple things easy. Which is why Perl 6 offers more convenience. Looking at sorting code, one can often find that the comparator duplicates code. Here are two common examples:

 # sort words by a sort order defined in a hash:
 my %rank = a => 5, b => 2, c => 10, d => 3;
 say sort { %rank{$^a} <=> %rank{$^b} }, 'a'..'d';
 #          ^^^^^^^^^^     ^^^^^^^^^^  code duplication

 # sort case-insensitively
 say sort { $^ cmp $^ }, @words;
 #          ^^^^^^     ^^^^^^  code duplication

Since we love convenience and hate code duplication, Perl 6 offers a shorter solution:

 # sort words by a sort order defined in a hash:
 say sort { %rank{$_} }, 'a'..'d';

 # sort case-insensitively
 say sort { .lc }, @words;

sort is smart enough to recognize that the code object code now only takes a single argument, and now uses it to map each element of the input list to new values, which it then sorts with normal cmp sort semantics. But it returns the original list in the new order, not the transformed elements. This is similar to the Schwartzian Transform, but very convenient since it's built in.

So the code block now acts as a transformer, not a comparator.

Note that in Perl 6, cmp is smart enough to compare strings with string semantics and numbers with number semantics, so producing numbers in the transformation code generally does what you want. This implies that if you want to sort numerically, you can do that by forcing the elements into numeric context:

 my @sorted-numerically = sort +*, @list;

And if you want to sort in reverse numeric order, simply use -* instead.

The unary sort is very convenient, so you might wonder why the Perl 5 folks haven't adopted it yet. The answer is that since the sort routine needs to find out whether the callback takes one or two arguments, it relies on subroutine (or block) signatures, something not (yet?) present in Perl 5. Moreover the "smart" cmp operator, which compares number numerically and strings lexicographically, requires a type system which Perl 5 doesn't have.

I strongly encourage you to try it out. But be warned: Once you get used to it, you'll miss it whenever you work in a language or with a library that lacks this feature.

Day 22 – A catalogue of operator types

Day 22 – A catalogue of operator types

Perl 6 has a very healthy relationship to operators. "An operator is just a funnily-named subroutine", goes the slogan in the community.

In practice, it means you can do this:

sub postfix:<!>($N) {
    [*] 2..$N;
say 6!;    # 720

Yeah, that’s the prototypical factorial example. I promise I won’t do it any more in this post. I swear the only reason we don’t have factorial as a standard operator in the language, is so that we can impress people by defining it.

Anyway, so a postfix operator ! is really just a "funnily-named" subroutine postfix:<!>. Similarly, we have prefix and infix operators, like prefix:<-> and infix:<*>. They’re all just subroutines. I wrote about that before, so I’m not going to hammer on that point.

Operators have different precedence (like infix:<*> binds tighter than infix:<+>)…

$x + $y * $z   # compiler sees $x + ($y * $z)
$x * $y + $z   # compiler sees ($x * $y) + $z

…and different associativity (like infix:</> associates to the left but infix:<=> associates to the right).

$x / $y / $z   # compiler sees ($x / $y) / $z
$x = $y = $z   # compiler sees $x = ($y = $z)

But I wrote about that before too, at quite some length, so I’m not going to revisit that topic.

No, today I just want to talk about the operator categories in general. I think Perl 6 does a nice job of describing the operator types themselves. I don’t see that in many other languages.

Here are all the different types:

 type            position           syntax
======          ==========         ========

prefix          before a term        !X
infix           between two terms    X ! Y
postfix         after a term         X!

circumfix       around               [X]
postcircumfix   after & around       X[Y]

A lot of other languages give you the ability to define your own operators. Many of them provide approaches which are hackish afterthoughts, and only allow you to override existing operators. Some other languages do approach the problem head-on, but end up simplifying the language to decrease the complexity of defining new operators.

Perl 6 approaches, and solves, the problem, head-on. You get all of the above operators, you can refine or override old ones, and you can talk within the language about things like precedence and associativity.

All that is rather nice. But, as usual, Perl 6 goes one step further and starts classifying metaoperators, too.

What’s a metaoperator? That’s our name for when you can extend an operator in a certain way. For example, many languages allow some kind of not-equal operator like infix:<!=>. Perl 6 has another one for string non-equality: infix:<ne>. And then maybe you want to do smart non-matching: infix:<!~~>. And so on — pretty soon you catch on to the pattern: you may, at one point or another, want to invert the result of any boolean matcher. So that’s what Perl 6 provides.

Here are a few examples:

normal op     negated op
=========     ==========
eq            !eq     ( synonym of ne )
~~            !~~
<             !<      ( synonym of >= )
before        !before

Because this particular metaoperator attaches itself before an infix operator, it gets the name infix_prefix_meta_operator:<!>. I was going to say "and yes, you can add your own user-defined metaoperators too", but currently no implementation supports that. Maybe sometime in the future.

There are many other categories of metaoperators. For example the "multiplication reducer" [*] that we used in the factorial example at the top (which takes a list of numbers and multiplies them all together) is really an infix:<*> surrounded by the metaop prefix_circumfix_meta_operator:sym<[ ]>. (It’s "prefix" because it goes before the list of numbers.)

Luckily, we don’t have meta-meta-ops. Already thinking about the metaops is quite a challenge sometimes. But what I like about Perl 6 and the approach it takes to grammar and operators is this: someone did think about it, long and hard. The resulting system has a pleasing simplicity to it.

Perl 6 is very well-suited for building parsers for languages. As one of its neatest tricks, it takes this expressive power and directs it towards the task of defining itself. As a Perl 6 user, you’re given not just an excellent toolbox, but a well-organized workshop to adapt and extend to fit your needs.

Day 21 – Signatures

Day 21 – Signatures

In today’s post, we’ll go through the basics of Perl 6’s subroutine signatures, which allow us to declare our parameters instead of coding them as we do in Perl 5.

In Perl 5, arguments to a sub are accessible via the @_ array, so if you want to access an argument to a sub, you can either access the array directly (which is typically only done where speed is a concern)…

use v5;
sub greet {
    print "Hello, " . @_[0] . "\n";

Or, more commonly, pull off any arguments as lexicals:

use v5;
sub greet {
    my $name = shift @_;
    print "Hello, $name\n";


Perl 6 lets you declare required positional arguments for your subs as part of the signature:

use v6;
sub greet($name) {
    print "Hello, $name\n";

Inside the sub, $name is available as a readonly alias to the passed in variable.

By default, parameters are required. If you try to call this function with no parameters as greet, you’ll get a compile time error:

Calling 'greet' requires arguments (line 1)
Expected: :($name)

You can make the parameter optional by adding a ? to the signature. Then you’ll have to examine the parameter to see if a defined value was passed in. Or, you can declare a default value to be used if none is passed in:

use v6;
sub guess($who, $what?) {
    # manually check to see if $what is defined

sub dance($who, $dance = "Salsa") {
dance("Rachael", "Watusi")

Another way to handle optional arguments is to use multis. Multis are subs that can have multiple implementations that differ by their signature. When invoking a multi, the argument list used in the invocation is used to determine which version of the multi to dispatch to.

use v6;
multi sub dance($who, $dance) {
    say "$who is doing the $dance";
multi sub dance($who) {
    dance($who, "Salsa");


The parameters in the previous section allow any type of value to be passed in. You can declare that only certain types are valid:

sub greet(Str $name) {
    say "hello $name";

Now hello("joe") will work as it did before. But hello(3) will generate a compile time error:

Calling 'greet' will never work with argument types (int) (line 1)
Expected: :(Str $name)

In addition to any of Perl 6 builtin types or user-built classes, you can also add programmatic checks inline in the signature with where clauses.

use v6;
multi odd-or-even(Int $i where * %% 2) { say "even" };
multi odd-or-even(Int $i) { say "odd"};

Note that we didn’t have to add a where clause to the second sub. The multi-dispatch algorithm will prefer the more detailed signature when it matches, but fallback to the less descriptive version when it doesn’t.

You can even use literal values as arguments. This style allows you to move some of your logic to the multi dispatcher.

use v6;
multi fib(1) { 1 }
multi fib(2) { 1 }
multi fib(Int $i) { fib($i-1) + fib($i-2) }

say fib(10);

Note that this isn’t very efficient… yet. Once the is cached trait for subs is implemented, we can use that to provide a builtin analog to Perl 5’s Memoize module.


Perl 6 provides for named parameters; if the positionals are analogous to an array of parameters, the named arguments are like a hash. You use a preceding colon in the argument declaration, and then pass in a pair for each parameter when invoking the sub.

use v6;
sub doctor(:$number, :$prop) {
    say "Doctor # $number liked to play with his $prop";
doctor(:prop("cricket bat"), :number<5>);
doctor(:number<4>, :prop<scarf>);

Note that the order the parameters are passed in doesn’t matter for named parameters.

If you have a variable of the same name in the calling scope, you can simplify the calling syntax to avoid creating an explicit pair.

use v6;
my $prop = "fez";
my $number = 11;
doctor(:$prop, :$number)

You can also use different names internally (using the expanded pair syntax) for the named arguments. This allows you to use different (simplified or sanitized) versions for the caller.

use v6;
sub doctor(:number($incarnation), :prop($accoutrement)) {
    say "Doctor # $incarnation liked to play with his $accoutrement";
my $number = 2;
my $prop = "recorder";
doctor(:$number, :$prop)


To support functions like sprintf, we need to be able to take a variable number of arguments. We call these args “slurpy”, since they “slurp” up the arguments.

# from rakudo's src/core/
sub sprintf(Cool $format, *@args) {

When invoking this sub, the first argument must be of type Cool (kind of a utility supertype), and all the remaining positional arguments are slurped up into the @args variable. The preceding * indicates the slurp.

Symmetrically, we can also slurp up named arguments into a hash.

# from rakudo's src/core/
my &callwith := -> *@pos, *%named {

This snippet introduces to the pointy block syntax for anonymous subs. The -> begins the declaration, followed by the signature (without parentheses), and finally the sub definition in the block. The signature here shows all the positionals ending up in *@pos, and all the named arguments in %named.

This also shows that positionals and named arguments can be combined in the same sub.


Method and sub declarations are virtually identical. All the parameters mentioned so far are usable in methods.

The main difference is that methods can be passed an invocant (the object associated with the method call), and when you define the sub, you have the opportunity to name it. It must be the first parameter if present, and is marked with a trailing :.

use v6;
method explode ($self: $method) {...}

Note that there is no comma separating these the invocant and the first positional. In this context, the colon functions as a comma.

Parameter Traits

Each parameter can additionally specify a trait that changes the behavior of that parameter:

  • is readonly – this is the default behavior for a parameter; the sub cannot modify the passed in value.
  • is rw – the argument can be modified. Forces the argument to be required.
  • is copy – the sub gets a modifiable copy of the original value.

More Information

Check out Synopsis #6 for more information, and the roast test suite for more examples – any of the directories starting with S06-.

Day 20 – How to mangle the initial state

Day 20 – How to mangle the initial state

The past year saw the (at least partial) implementation of several variable traits. But before we get into that, the past year also saw Nil getting implemented closer to spec in Rakudo. If you read the spec, you will know that Nil indicates the absence of a value. This is different from being undefined, as we saw in an earlier blogpost this year. So what does that mean?

$ perl6 -e 'my $a = 42; say $a; $a = Nil; say $a'

So, assigning Nil will reset a scalar container to its default value, which (by default) is the type object of that container. Which is (Any) if nothing is specifically specified.

Enter the “is default” variable trait

If you want to specify the default value of a variable, you can now use the “is default” variable trait:

$ perl6 -e 'my $a is default(42); say $a; say $a.defined’

So oddly enough, even though we haven’t assigned anything to the variable, it now has a defined value. So let’s assign something else to it, and then assign Nil:

$ perl6 -e 'my $a is default(42) = 69; say $a; $a = Nil; say $a'

Of course, this is a contrived example.

“is default” on arrays and hashes

It gets more interesting with arrays and hashes. Suppose you want a Bool array where you can only switch “off” elements by assigning False? That is now possible:

$ perl6 -e 'my Bool @b is default(True); say @b[1000]; @b[1000]=False; say @b[1000]'

Of course, type checks should be in place when specifying default values.

$ perl6 -e 'my Bool $a is default(42)'
===SORRY!=== Error while compiling -e
Type check failed in assignment to '$a'; expected 'Bool' but got 'Int’

Note that this type check is occurring at compile time. Ideally, this should also happen with arrays and hashes, but that doesn’t happen just yet. Patches welcome!

Using is default on arrays and hashes interacts as expected with :exists (well, at least for some definition of expected :-):

$ perl6 -e 'my @a is default(42); say @a[0]; say @a[0].defined; say @a[0]:exists'

Note that even though each element in the array appears to have a defined value, it does not necessarily exist. Personally, I would be in favour of expanding that to scalar values as well, but for now :exists does not work on scalar values, just on slices.

It’s not the same as specifying the type

What’s wrong with using type objects as default values? Well, for one it doesn’t set the type of the variable. Underneath it is still an (Any) in this case:

$ perl6 -e 'my $a is default(Int) = "foo"; say $a'

So you don’t get any type checking, which is probably not what you want (otherwise you wouldn’t take all the trouble of specifying the default). So don’t do that! Compare this with:

$ perl6 -e 'my Int $a = "foo"'
Type check failed in assignment to '$a'; expected 'Int' but got 'Str'

Which properly tells you that you’re doing something wrong.

Nil assigns the default value

Coming back to Nil: we already saw that assigning it will assign the default value. If we actually specify a default value, this becomes more clear:

$ perl6 -e 'my $a is default(42) = 69; say $a; $a = Nil; say $a'

In the context of arrays and hashes, assigning Nil has a subtly different effect from using the :delete adverb. After assigning Nil, the element still exists:

$ perl6 -e 'my @a is default(42) = 69; say @a[0]; @a[0] = Nil; say @a[0]:exists'

Compare this with using the :delete adverb:

$ perl6 -e 'my @a is default(42) = 69; @a[0]:delete; say @a[0]; say @a[0]:exists'

One could argue that assigning Nil (which assigns the default value, but which is also specced as indicating an absence of value) should be the same as deleting. I would be in favour of that.

Argh, I want to pass on Nil

The result of a failed match, now also returns Nil (one of the other changes in the spec that were implemented in Rakudo in the past year). However, saving the result of a failed match in a variable, will assign the default value, losing its Nilness, Nilility, Nililism (so much opportunity for creative wordsmithing :-).

$ perl6 -e 'my $a = Nil; say $a'

It turns out you can specify Nil as the default for a variable, and then It Just Works™

$ perl6 -e 'my $a is default(Nil) = 42; say $a; $a = Nil; say $a'


You can use the VAR macro to introspect variables to find out its default value, without having to do something as destructive as assigning Nil to it:

$ perl6 -e 'my @a is default(42); say @a.VAR.default'

This also works on system variables like $/:

$ perl6 -e 'say $/.VAR.default'

And can also be used to interrogate other properties:

$ perl6 -e 'say $/.VAR.dynamic’

But this gets us into material for a blog post for another day!


The “is default” variable trait allows you to manipulate the default value of variables and elements in arrays and hashes. Together with the new meaning of Nil, it is a powerful means of mangling initial values of variables to your satisfaction.

Day 19 – Perl 6 Supplies Reactive Programming

Day 19 – Perl 6 Supplies Reactive Programming

Several days back, we took a look at promises and channels. Promises provided a synchronization mechanisms for asynchronous things that produced a single result, while channels were ideal for setting up producer/consumer style workflows, with producers and consumers able to work in parallel. Today we’ll take a look at a third mechanism aimed at introducing asynchrony and coping with concurrency: supplies!

Synchronous = Pull, Asynchronous = Push

One of the most important features of promises is the then method. It enables one or more things to be run whenever the asynchronous work the promise represents is completed. In a sense, it’s like a publish/subscribe mechanism: you call then to subscribe, and when the work is done then the notification is published. This happens asynchronously. You don’t sit around waiting for the promise to complete, but instead just say what to do when this takes place. Thinking about the way data flows, values are pushed along to the next step of the process.

This is rather different to things like sub and method calls. There, we make the call, then we block until it has completed. Iterating over a lazy list is the same: you can’t progress with the iteration until the next value is available. Thus, iteration is really about pulling stuff from a source. So, if a promise can be thought of as something that can push a single values out as it becomes available, do we have something that can push a whole stream of values outwards, as they are produced over time?

Supplies! We do!

A while back, it was realized that the observer pattern is the mathematical dual of the iterator pattern. Why is this exciting? Quite simply, because it means that all the things you can sensibly do with something you can iterate (map, grep, zip, etc.), you can also sensibly do with something you can observe. Out of this was born reactive programming, and the Rx (Reactive Extensions) library, which has now been ported to many platforms. In Perl 6, we’re providing support for this in core.

The basics

Let’s start out simple. First, we create a new Supply:

my $measurements =;

We can then tap the supply, passing a closure that should be called whenever a value is made available:

$measurements.tap(-> $value {
    say "Measured: $value";

Finally, we produce some values:


On each of these calls, the closure we tapped the supply with is invoked. Just as we can call then many times, so we can tap many times too:

$measurements.tap(-> $value {
    say "Also measured: $value";

Now, when we produce a value:


Both of the closures tapping the supply will be called. Note that tap returns an object which can be used to express you’re no longer interested in the supply, essentially turning that tap off.

Note that we didn’t introduce any asynchrony so far. However, supplies are built for it. You can safely have multiple threads supplying values. By default, the supplying thread is used to execute the taps.

Enter the combinators!

Since supplies are essentially a thread-safe observer implementation, we can define many of the same things on them as we’re used to having on lists. For example, imagine we just wanted to tap high measurements. Well, we just re-use knowledge from how we’d filter a list: using grep!

$measurements.grep(* > 4).tap(-> $value {
    say "HIGH: $value";

Calling grep on a supply produces another supply, just as calling grep on a list gives another list. We could, if we wished, store it in a variable and tap this derived supply many times, grep it again, map it, etc.

Supply factories

There are ways to get supplies besides simply creating them directly. The Supply class has various factory methods that create various interesting kinds of supply, while introducing asynchrony. For example, interval gives a supply that, when tapped, will produce an ascending integer once per time interval.

my $secs = Supply.interval(1);
$secs.tap(-> $s { say "Started $s seconds ago" });
sleep 10;

Factories can also help map between paradigms. The Supply.for method produces a supply that, when tapped, will iterate the specified (potentially lazy) list and push the values out to the tapper. It does the iteration asynchronously. While it’s not implemented yet, we’ll be able to define a similar mechanism for taking a Channel and tapping each value that is received.

Crossing the streams

Some of the most powerful – and tricky to implement – combinators are those that involve multiple supplies. For example, merge gives a single supply whose values are those of the two other supplies it tapped, and zip pairs together values from two different supplies. These are tricky to implement because it’s entirely possible that two different threads will be supplying values. Thankfully, though, we just need to manage this once inside of the supplies implementation, and save those using them from worrying about the problem! In a sense, combinators on lists factor out flow control, while combinators on supplies factor out both flow control and synchronization. Both let us program in a more declarative style, getting the imperative clutter out of our code.

Let’s bring all of this together with an example from one of my recent presentations. We simulate a situation where we have two sets of readings coming in: first, measurements from a belt, arriving in batches of 100, which we need to calculate the mean of, and second another simpler value arriving once every 5 seconds. We want to label them, and get a single supply merging these two streams of readings together. Here’s how it can be done:

my $belt_raw = Supply.interval(1).map({ rand xx 100 });
my $belt_avg = $ (@values) {
    ([+] @values) / @values
my $belt_labeled = ${ "Belt: $_" });
my $samples = Supply.interval(5).map({ rand });
my $samples_labeled = ${ "Sample: $_" });
my $merged = $belt_labeled.merge($samples_labeled);
sleep 20;

Notice how it’s not actually that much harder than code that maps and greps lists we already had – and yet we’re managing to deal with both time and concurrently arriving data.

The future

Supplies are one of the most recently implemented things in Rakudo, and what’s done so far works on Rakudo on the JVM. With time, we’ll flesh out the range of combinators and factories, keep growing our test coverage, and deliver this functionality on Rakudo on MoarVM too, for those who don’t want to use the JVM.

Day 18 – A Grammar with duplicate checking

Day 18 – A Grammar with duplicate checking

Today’s example constructs a grammar for tracking playing cards in a single deal. We’ll say it’s poker with one or more players and that each player is being dealt a hand that contains exactly five cards.

There is, however, the need to detect duplicate cards. We’ll need some way of tracking cards both within each card-hand and between hands.

A simple Card Game Grammar

To start with, here’s the basic grammar (no duplicate checks yet):

grammar CardGame {

    rule TOP { ^ <deal> $ }

    rule deal {
        <hand>+ % ';'

    rule hand { [ <card> ]**5 }
    token card {<face><suit>}

    proto token suit {*}
    token suit:sym<♥>  {<sym>}
    token suit:sym<♦>  {<sym>}
    token suit:sym<♣>  {<sym>}
    token suit:sym<♠>  {<sym>}

    token face {:i <[2..9]> | 10 | j | q | k | a }

say CardGame.parse("2♥ 5♥ 7♦ 8♣ 9♠");
say CardGame.parse("2♥ a♥ 7♦ 8♣ j♥");

The  top-level rule consists of a deal. The deal consists of one or more hands separated by ';'. Each hand consists of 5 playing cards.

Each card is represented by a face, one of: a (ace), j (jack), q (queen) or k (king), or 2 – 10. This is followed by a suite: ♥ (hearts) ♦ (diamonds) ♣ (clubs) or ♠ (spades).

[We could have used the playing cards characters, newly introduced in Unicode 6.0, but these aren’t widely supported yet].

As expected, the first cut of the grammar cheerily parses any hand:

say CardGame.parse("a♥ a♥ 7♦ 8♣ j♥");
# one hand, duplicate a♥
say CardGame.parse("a♥ 7♥ 7♦ 8♣ j♥; 10♥ j♥ q♥ k♥ a♥");
# two hands, duplicate j♥

Detecting Duplicates

We start by adding a Perl 6 variable declaration to the grammar. This will be used to track cards:

rule deal {
    :my %*PLAYED = ();
    <hand>+ % ';'

This declares %*PLAYED [1]. The '%*' twigil  indicates that it’s a hash '%' and that’s dynamically scoped '*'.

Dynamic scoping is not only for subroutine and method calls [1]. It also works seamlessly with grammar rules, tokens and actions.

Being dynamically scoped, %*PLAYED is available to callees of the deal rule; the hand token, and its callee, the card token.

It’s also available to any actions, that then get called. So we can track and report on duplicates by creating an action class with a method for the card token:

class CardGame::Actions {
    method card($/) {
       my $card = $/.lc;
       say "Hey, there's an extra $card"
           if %*PLAYED{$card}++;

my $a =;
say CardGame.parse("a♥ a♥ 7♦ 8♣ j♥", :actions($a));
# "Hey there's an extra a♥"
say CardGame.parse("a♥ 7♥ 7♦ 8♣ j♥; 10♥ j♥ q♥ k♥ a♦",
# "Hey there's an extra j♥"

And that might be all that’s needed  for tracking and reporting on duplicates. There’s a pretty good separation between the declarative grammar and procedural actions, with just one dynamically scoped hash variable.

Disallowing Duplicates

But I had a situation where I wanted duplicate checking to be a parsing constraint. Parsing needed to fail when duplicates were encountered.

I achieved this by moving the duplicate check grammar side:

token card {<face><suit>
        # only allow each card to appear once
        my $card = $/.lc;
        say "Hey, there's an extra $card"
            if %*PLAYED{$card};

        ! %*PLAYED{$card}++;

This has introduced a code assertion between the <?{ and }>  [2]. The rule succeeds when the code evaluates to a True value. The card token thus fails when the same card is detected more than once in a single deal.

say CardGame.parse("2♥ 7♥ 2♦ 3♣ 3♦");
# legitimate, parses

say CardGame.parse("a♥ a♥ 7♦ 8♣ j♥");
# fails with message: Hey, there's an extra a♥

say CardGame.parse("a♥ 7♥ 7♦ 8♣ j♥; 10♥ j♥ q♥ k♥ a♦");
# fails with message: Hey, there's an extra j♥


One thing to be careful of with this type of technique is back-tracking (trying of alternatives). If, for instance, the grammar was modified in such a way that the card token could be called more than once for single input card, then we might erroneously report a duplicate. It’s still possible to track, but becomes a bit more involved. The simplest answer is to keep the grammars as simple as possible and minimize back-tracking.

If in any doubt,  please consider using one or more of the Grammar::Debugger, Grammar::Tracer [3] or the debugger [4] modules [5] to track what’s going on. You can also insert debugging code into tokens or rules as closures: { say "here" } [6].

That the exercise for today; a simple Perl 6 Grammar to parse playing-cards in a card-game, but with duplicate checks using either actions or code assertions.