A couple of days ago, while prototyping the solution to a problem I had, I wrote a bit of code that brought immense joy to me. It was the kind of code that makes you giggle each time you see it run just because of how clever and elegant the solution seems, and because of the excitement of proving that, against your expectations, it actually works.

Wanting to share the excitement, I shared it online. The snippet looked like this:

sub foo ( $a, $b ) { $a ~ $b }

my $wh;

$wh = &foo.wrap: {
    LEAVE &foo.unwrap: $wh;
    callwith( $^b, $^a );
}

say foo( 1, 2 ) for 1 .. 3;

This is very dense.

And a bit cryptic.

And hella fun.

So let’s break it down. To do this, we’ll start from the end, and work our way back to the beginning.

The results

When the code above gets executed, it prints out the following lines:

21
12
12

This is the result of the final line:

say foo( 1, 2 ) for 1 .. 3;

which prints the result of calling foo( 1, 2 ) three times. This line will be familiar to Perl programmers because Raku supports “statement modifiers”, which it inherited from Perl: the for at the end of the statement modifies the statement that comes before, and executes it once for each element in the 1 .. 3 range (which is actually a Range object).

But if we are calling foo( 1, 2 ) three times, then why does it output 21 the first time we call it, and 12 the rest of the times?

Wrapping code

That’s because of the previous block:

my $wh;

$wh = &foo.wrap: {
    LEAVE &foo.unwrap: $wh;
    callwith( $^b, $^a );
}

This bit of code is where the core of the magic happens. ✨

The first bit that matters is the call to wrap This is called on the foo subroutine object (which is why we reference it with the & sigil, otherwise we might call the function rather than get a reference to it).1

The wrap method allows us to attach a block of code to foo, so that calling that function will execute the block of code instead.

Re-dispatch

Inside the block we are using to wrap foo we use callwith to be able to call the wrapped subroutine. We could use a number of different alternatives depending on whether we wanted to get a return value and whether we wanted to modify the arguments the underlying function gets called with.

In this case, callwith allows us to modify the arguments, but it never returns. And we modify the arguments by calling it like callwith( $^b, $^a ).

But where did these variables come from?

Self-declared positionals

They are self-declared positional arguments.

When a block does not define an explicit list of arguments, any variables used within its scope that use the ^ twigil (= any variable with a ^ after the sigil) declares an implicit positional argument. Each positional the block receives will get assigned to these variables in alphabetical order.

In the example above, then, the call callwith( $^b, $^a ) will re-dispatch to the function we are wrapping, with the first and second arguments switched. Since the original subroutine concatenates both arguments (with the ~ operator), this explains the first line of output: we call foo( 1, 2 ) and this re-dispatches to foo( 2, 1 ) which results in the 21 line.

Progress!

Now for the truly magic bit.

Self-unwrapping wrappers

Before actually re-dispatching to the original code, we have another line:

LEAVE &foo.unwrap: $wh;

This line uses a LEAVE phaser to register a statement to be called when execution leaves the current block. So after switching the arguments and re-dispatching to the original subroutine, execution leaves the block and this statement finally gets executed.

When it does, it calls the unwrap method on foo to remove the wrapping code (it does this by passing in the wrapping handle that was stored in the $wh variable).

Wrap-up

And that’s it! The snippet defines a foo subroutine that takes two arguments and concatenates them. It then wraps it into a block of code that swaps the arguments before calling the original subroutine, and then removes itself as if it was never there.

This explains the output: the first time we call foo( 1, 2 ) the arguments get swapped and we print 21, but on subsequent calls there is no wrapping code anymore, so we get lines like 12.

What a mouthful! But all of that in seven lines of code. Raku can really pack a punch. ✊

That’s nice, but what’s the real use?

Incidentally, this was something that I was prototyping to solve a real problem: I had a callback that would get called repeatedly, and I wanted to hook into the first time that callback was executed so I could run a preliminary check. But once the check had passed, there was no point in doing it every time. Unwrap to the rescue.

  1. Incidentally, this makes use of another useful Raku feature: in Raku everything is an object. This is what allows us to, for example, seamlessly call methods on subroutines.