## ðŸ“˜ Atomic operations in Perl 6

Using the solution for Task 38,Â the Monte Carlo method, create a program that calculates the result using multiple threads.

Perl 6 has built-in support for parallel computing. In Task 92,Â Sleep Sort, weâ€™ve seen how to use the keywordsÂ `await`,Â `gather`, andÂ `take` to spawn a few threads and wait for them to finish.Â

When different threads want to modify the same variable, such as a counter, it is wise to introduce atomic operations to make sure the threads do not interfere with each other. Here is the modification of the Monte Carlo program calculating the area of a circle with four parallel threads.

`my atomicint \$inside = 0;my \$n = 5000;my \$p = 4;await gather for 1..\$p {    take start {        for 1..\$n {            my @point = map {2.rand - 1}, 1..2;            \$insideâš›++ if sqrt([+] map *Â², @point) <= 1;        }    }}say 4 * \$inside / \$p / \$n;`

Run the program a few times, changing the value ofÂ `\$n` (the number of random points per thread) andÂ `\$p` (the number of threads). The program should print the value that is close toÂ pi, such asÂ 3.141524.

The new thing here is the atomic increment operation:

`\$insideâš›++`

An atomic operation ensures that the variable is modified with no conflicts between the threads.

The variable itself should be a native integer of a special typeâ€”notice how it is declared:

`my atomicint \$inside;`

As the atomic operation uses the Unicode character, there is an ASCII alternative:

`atomic-fetch-inc(\$inside)`

Hereâ€™s a list of other atomic operations and their synonyms that can be used with parallel processes:

`\$var âš›= \$value       atomic-assign(\$var, \$value)my \$a = âš›\$var         my \$a = atomic-fetch(\$var)\$varâš›++               atomic-fetch-inc(\$var)\$varâš›--               atomic-fetch-dec(\$var)++âš›\$var               atomic-inc-fetch(\$var)--âš›\$var               atomic-dec-fetch(\$var)\$var âš›+= \$value       atomic-fetch-add(\$var, \$value)\$var âš›-= \$value       atomic-fetch-dec(\$var, \$value)`

N. B. The code in this task works with the Rakudo Perl 6 compiler starting from version 2017.09. Earlier versions do not support atomic operators.

## ðŸ“˜ Sleep Sort in Perl 6

Implement the Sleep Sort algorithm for a few small positive integer values.

The Sleep Sortis a funny implementation of the sorting algorithm. For each input value, an asynchronous thread starts, which waits for the number of seconds equals to the input number and then prints it. So, if all the threads are spawned simultaneously, the output of the program contains the sorted list.

Here is the solution in Perl 6. On the next page, we will go through the bits of it and explain all the important moments.

`await gather for @*ARGS -> \$value {    take start {        sleep \$value/10;        say \$value;    }}`

Pass the values via the command line, and get them sorted.

`\$ perl6 sleep-sort.pl 9 10 2 8 5 7 6 4 1 3123...8910`

The input values from the command line come to theÂ `@*ARGS` array. The first step is to iterate over the array:

`for @*ARGS -> \$value {         . . .}`

For eachÂ `\$value`, theÂ startblock creates a promise with a code block that waits for the time that is proportional to the value and prints the value after that time.

`start {    sleep \$value/10;    say \$value;}`

Dividing the value by ten speeds up the program. On the other hand, the delay should not be too small to avoid race conditions between different threads.

After a separate promise has been created for each input number, the program has to wait until all of them are kept. To achieve that, theÂ `gather`â€”`take` construction is used. TheÂ `take` keyword adds another promise to a sequence, which is then returned as a whole by theÂ `gather` keyword.

`gather for @*ARGS -> \$value {    take start {        . . .    }}`

Finally, theÂ `await` routine ensures the program does not quit until all the promises are kept or, in other words, until all the numbers are printed.

```await gather . . . {
Â Â Â Â take start {
Â Â Â Â Â Â Â Â . . .
Â Â Â Â }
}```

## ðŸ“˜ Setting timeouts in Perl 6

Do not wait for a slow code block if it takes too long.

In Perl 6, promises are the best way to create timeouts. In the following example, two code blocks are created; they are executed in parallel.

`my \$timeout = Promise.in(2).then({    say 'Timeout after 2 seconds';});my \$code = start {    sleep 5;    say 'Done after 5 seconds';}`

BothÂ `\$timeout` andÂ `\$code` are the promises, i. e. objects of theÂ `Promise` type. Actually, theÂ `\$timeout` variable is a promise that is executed as a result of keeping the anonymous promise created by theÂ `Promise.in(2)` call. TheÂ `in` method of theÂ `Promise` class creates a promise that becomes kept after the given number of seconds.

The second promise, stored in theÂ `\$code` variable, is created by theÂ `start` function. This is a long-running code block, which does not return within five seconds. TheÂ `\$code` promise can be kept only after that time.

TheÂ `\$timeout` promise is kept earlier than theÂ `\$code` one. To let the program continue earlier, create another promise with the help of theÂ `anyof` method:

`await Promise.anyof(\$timeout, \$code);say 'Alldone';`

The flow of the whole program is the following: first, theÂ `\$timeout` code block is created and starts running in a separate thread. Then, without waiting, theÂ `\$code` block has been created and launched. Finally, the next line of the main thread is executed; it creates an anonymous thread and waits until it is kept. TheÂ `await` routine blocks the execution of the main program until at least one of its arguments is kept. This program prints `â€˜Alldoneâ€™` after two seconds, and exits:

`\$ perl6 timeout.pl Timeout after 2 secondsAll done`

If theÂ `\$code` thread is completed first (say, if we changed the timeout value to 10 seconds), then the output is different, and the timeout is not triggered:

`\$ perl6 timeout.pl Done after 5 secondsAll done`

Keep in mind that in our examples, the program finishes after printing `â€˜All doneâ€™`. In case the program continues after that, the longest promise will still be running.

For example, add a simple delay like the one shown below:

`await Promise.anyof(\$timeout, \$code);say 'All done';sleep 20;`

In this case, the program prints all three messages:

`\$ perl6 timeout.plÂ Timeout after 2 secondsAll doneDone after 5 seconds`

## ðŸ“˜ Computing leap years in Perl 6

Tell if the given year is leap or common.

The algorithm for detecting whether the year is leap includes a few divisibility tests. Take an extract in the pseudocode from Wikipedia:

ifÂ (yearÂ is notÂ divisibleÂ by 4)Â thenÂ (it is a common year)
else ifÂ (yearÂ is not divisible by 100)Â thenÂ (it is a leap year)
else ifÂ (yearÂ is not divisible by 400)Â thenÂ (it is a common year)
elseÂ (it is a leap year)

It is possible to implement the above sequence of ifs and elses in Perl 6, but it is a better idea to join conditions using the logical operators.

`my \$year = 2018;say (\$year %% 400 or \$year % 100 and \$year %% 4) ??    'Leap' !! 'Common';`

Notice that both the moduloÂ `%` and divisibilityÂ `%%` operators are used, which allow avoiding Boolean negations in the sub-conditions.

The following program prints the list of leap years in the range 1800â€“2400:

`for 1800 .. 2400 -> \$year {    say \$year if \$year %% 400 or \$year % 100 and \$year %% 4;}`

There may be some considerations regarding the efficiency of the sequence of the checks because each year is first tested against 400, while it may be more optimal to check first if the year is divisible by 4. If this becomes an important argument, then theÂ `if``else` chain may be more efficient. To achieve an even higher speed, a pre-calculated array of leap years is better.

## ðŸ“˜ Datetime arithmetic in Perl 6

Find the difference between the two dates. Add a given number of days to the date.

TheÂ `DateTime` class in Perl 6 defines theÂ `+` andÂ `â€“` operators, which can be used in combination with either anotherÂ `DateTime` object or with theÂ `Duration` object.

Let us first find the difference between the two given dates:

`my \$date1 = DateTime.new('2017-12-31T23:59:50');my \$date2 = DateTime.new('2018-01-01T00:00:10');say \$date2 - \$date1; # 20`

The type of theÂ `\$date2 - \$date1` expression isÂ `Duration`. In the numeric context, it returns the number of seconds. Therefore, there are 20 seconds between our dates at hand.

AÂ `Duration` object can also be used instead of the secondÂ `DateTime` object.

For example, increase the given date by two minutes:

`my \$now = DateTime.now();my \$when = \$now + Duration.new(120);say "\$now -> \$when";`

Or learn what were the date and time a week ago:

`my \$back = \$now - Duration.new(3600 * 24 * 7);say \$back;`

In the current design of the language, the constructor of theÂ `Duration` class needs a number of seconds.

## ðŸ“˜ Formatted date in Perl 6

Print the current date in an even better format.

In Perl 6, there is a built-inÂ `DateTime` class. It is equipped with a few useful methods, so thereâ€™s no need to use external modules for many standard tasks. Save the current moment in theÂ `\$now` variable:

`my \$now = DateTime.now;`

The easiest thing is to print the proper time using a dedicated method:

`say \$now.hh-mm-ss; # 22:37:16`

To achieve a more granular control over both the date and time parts, use theÂ `formatter` attribute of the constructor together with methods likeÂ `day` andÂ `month` to get separate parts of the date and time (see Task 87,Â Current date and time):Â

`my \$now = DateTime.now(    formatter => {        sprintf '%02d.%02d.%04d, %02d:%02d',         .day, .month, .year, .hour, .minute    });say \$now; # 14.10.2017, 22:41`

The formatting stringÂ `'%02d.%02d.%04d, %02d:%02d'` uses the standard POSIXÂ `printf` format. TheÂ `sprintf` function forms a string that is returned when aÂ `DateTime` object (theÂ `\$now` variable, in our case) is stringified. For instance, it is used when the variable is interpolated in a string:

`say "Current date and time: \$now.";`

## ðŸ“˜ Current date and time in Perl 6

Print current date and time as an epoch and in a human-readable format.

In Perl 6, the `time` function returns the current time as the Unix epoch:

`say time;`

The output is something like this: `1495785518`.

For manipulating dates and times, use the built-in `DateTime` class:

`say DateTime.now;`

The date is now in a more human-readable format, although still is overloaded with many details: `2017-05-26T10:02:20.500209+02:00`.

To access the separate elements of date and time, use the methods on the variable of the `DateTime` class:

`my \$dt = DateTime.now;say \$dt.day;   # 26say \$dt.month; # 5say \$dt.year;  # 2017say \$dt.hour;  # 10say \$dt.minute; # 9say \$dt.second; # 5.55802702903748`

The meaning of all the elements is quite straightforward.

All the values except seconds are integer. For the seconds, you may want to take the integer part only:

`say \$dt.second.Int;`