In Perl 5, I used to set timeouts using signals (or, at least, that was an easy and predictable way). In Perl 6, you can use promises. Let us see how to do that.

To imitate a long-running task, create an infinite loop that prints its state now and then. Here it is:

for 1 .. * {
.say if $_ %% 100_000;
}

As soon as the loop gets control, it will never quit. Our task is to stop the program in a couple of seconds, so the timer should be set before the loop:

Promise.in(2).then({
exit;
});
for 1 .. * {
.say if $_ %% 100_000;
}

Here, the Promise.in method creates a promise that is automatically kept after the given number of seconds. On top of that promise, using then, we add another promise, whose code will be run after the timeout. The only statement in the body here is exit that stops the main program.

Of course, the idea was to increase the counter by 1 million in all of the ten threads, but about ⅓ of the steps were lost. It is quite easy to understand why that happens: the parallel threads read the variable and write to it ignoring the presence of other threads and not thinking that the value can be changed in-between. Thus, some of the threads work with an outdated value of the counter.

Perl 6 offers a solution: atomic operations. The syntax of the language is equipped with the Atom Symbol (U+0x269B) ⚛ character (no idea of why it is displayed in that purple colour). Instead of $c++, you should type $c⚛++.

A few other operators can be atomic, for example, prefix and postfix increments and decrements ++ and --, or += and -=. There are also atomic versions of the assignment operator = and the one for reading: ⚛ (sic!).

If you need atomic operations in your code, you are not forced to use the ⚛ character. There exists a bunch of alternative functions that you can use instead of the operators:

When you print an object, say, as say $x, Perl 6 calls the gist method. This method is defined for all built-in types: for some of them, it calls the Str method, for some the perl method, for some types it makes the string representation somehow differently.

In these cases, the proto-function returns {*}, which makes Perl 6 trying other candidates. As we have enough candidates for both integer and string arguments, the compiler can easily choose one of them:

The EVAL routine in Perl 6 compiles and executes the code that it gets as an argument. Today, we will see some potential use cases that you may try in your practice. Tomorrow, we will dig into Rakudo sources to see how it works and why it breaks sometimes.

1

Let us start with evaluating a simple program:

EVAL('say 123');

This program prints 123, there’s no surprise here.

2

There are, though, more complicated cases. What, do you think, does the following program print?

EVAL('say {456}');

I guess it prints not what you expected:

-> ;; $_? is raw { #`(Block|140570649867712) ... }

It parses the content between the curly braces as a pointy block.

3

What if you try double quotes?

EVAL("say {789}");

Now it even refuses to compile:

===SORRY!=== Error while compiling eval.pl
EVAL is a very dangerous function!!! (use the MONKEY-SEE-NO-EVAL pragma to override this error,
but only if you're VERY sure your data contains no injection attacks)
at eval.pl:6
------> EVAL("say {789}")⏏;

4

We can fix the code by adding a few magic words:

use MONKEY-SEE-NO-EVAL;
EVAL("say {789}");

This time, it prints 789.

5

The code is executed (we don’t know yet when exactly, that is the topic of tomorrow’s post), so you can make some calculations, for example:

use MONKEY-SEE-NO-EVAL;
EVAL("say {7 / 8 + 9}"); # 9.875

6

Finally, if you try passing a code block directly, you also cannot achieve the goal, even with a blind monkey:

The parameter in square brackets after the role name restricts both the type of the $.value attribute and the return type of the methods, which return a new object of the type T. Here, in the template of the role, T is just a name, which should later be specified when the role is used.

Using the role

So, let’s make it integer:

class N does R[Int] {}

Now the parts of the role that employ the T name replace it with Int, so the class is equivalent to the following definition: