Category: Advent calendar

Today, we’ll answer the question of what’s the date today (and tomorrow we can talk about palindromes if you want).

So, to print the answer, you can use the following line of Perl 6 code:

DateTime.now.yyyy-mm-dd.say

It looks transparent and prints the date in the format of YYYY-MM-DD. The good part is that the DateTime class is available straight ahead, and you don’t need to include a module as you do in Perl 5, for example.

$ perl6 -e'DateTime.now.yyyy-mm-dd.say'2018-12-05

As you have already seen in the previous days of the calendar, chaining method calls is a typical Perl 6 thing. An opposite alternative would be to use say as a subroutine and use parentheses to mark method calls:

say(DateTime.now().yyyy-mm-dd());

This code also works; it is completely correct, but it looks heavy.

What you should also notice and tell your friends, is that in Perl 6, you can use dashes and apostrophes in identifiers.

Well, maybe using apostrophes is not a great idea, but hyphens are used very widely already in the source code of Perl 6. Just make sure you put spaces around minus operator in expressions to avoid any conflicts in parsing.

Exploring the sources or reading the documentation, you will find another method named in the same manner: hh-mm-ss. I bet you understand what it does.

> DateTime.now.hh-mm-ss.say00:12:01

Notice that you will not find similar methods for different formats of the output, such as dd-mm-yy or hh-mm. Use formatter instead. It is not a method but an attribute defined in the Datish role. There is a default formatter in the DateTime class, but you may redefine it by providing the constructor with your own subroutine, for example:

Perl 6 is operating with arbitrary-long integers by default; you don’t need to include any modules or somehow else activate this behaviour. You can even calculate powers and get the result quickly enough:

$ perl6 -e'say 37107287433902102798797998220837590 ** 1000'

Another thing to notice is that we can transparently cast strings to numbers and vice versa. In our today’s program, the list of numbers is presented as a quoted list of strings within a pair of angle brackets.

On the list, you call the sum method, which works with numbers. After getting the sum, you treat it as a string again and extract the first ten characters of it. The whole code looks very natural and easy to read.

That’s the whole program, and it generates random numbers below 2019! It only uses method calls, chained one after another. If you have never seen Perl 6 before, the first thing you notice here is a method called on a number. In Perl 6 that’s not something extraordinary.

Calling the rand method on a number potentially is a call of the method defined in the Cool class, which is immediately delegated to a numeric representation of the number:

If you want to understand the quality of the random number generator, dig deeper to NQP and MoarVM, and later to the backend engine of the virtual machine. To make the results repeatable (e. g., for tests), set the seed by calling the srand function:

Welcome to Day 2 of the Perl 6 One-Liner Advent Calendar! Today, we’ll solve a nice task from Project Euler with number 1. Once again, let me warn you that the rest of the text contains a solution, so you are welcome to make a pause to think of your own solution first. But I am almost sure that if you are reading perl6.online then you most likely solved the problems from Project Euler in the past.

The task is to find the sum of all multiples of 3 and 5 below 1000. The first elements of the row of our interest are 3, 5, 9, 15, 20, 21, etc. You can already see that some of them, such as 15, are multiples of both 3 and 5, so it is not possible to add up multiples of 3 and 5 separately.

The short story is here:

say sum((1..999).grep: * %% (3 | 5))

Now let us decipher it.

What we need is to filter the numbers that are multiples of either 3 or 5. If you re-read the previous sentence, a bell should ring for you: in Perl 6 this can be achieved with junctions, informally known as quantum superpositions. To test if a number is dividable by either 3 or 5, write the following:

$x %% 3 | 5

By the way, %%, the divisibility operator, is a very sweet thing that helps avoiding negations in Boolean tests, which you would have written as follows, would you only have a single percent:

!($x % (3 | 5))

OK, the main condition is ready, let us scan the numbers between 1 and (including) 999:

(1..999).grep: * %% (3 | 5)

A few more interesting Perl 6 elements appear here. For example, the WhateverCode block, which was introduced by a * character (learn more about it in my article All the stars of Perl 6 published in the previous Perl 6 Advent Calendar). Together with the colon-form of method calls, it allows to get rid of a nested pair of braces and parentheses:

(1..999).grep({$_ %% (3 | 5)})

The numbers are filtered (grepped if you prefer), and it’s time to add them up and print the result. We come to the final one-liner shown at the beginning of this post.

Of course, instead of writing say sum(...) one could do a method call or two:

Welcome to the first day of the brand new Perl6.Online AdventCalendar! This year, its theme is Perl 6 One-Liners (a pun from perl6.onliners). Thus, welcome to this year’s Perl 6 One-Liner Advent Calendar. The whole perl6.online blog was initially planned to be daily, so it’s a great opportunity to keep the pace for at least another 25 days.

Don’t forget to follow other Perl-related calendars written by other people:

In the following days, I will be publishing short articles that either explain the code from the Perl 6 Calendar 2019 or solve some problems inspired by Project Euler, where Perl 6 can demonstrate its extreme beauty (if you don’t want to see my solutions prior to yours, I invite you to solve the tasks yourself first, and only then read the articles). But today, let’s start with something else and generate a random password in Perl 6.

The join method is defined in the List class too. Let’s not examine the body of it now, as it is quite big, but let’s look at the signature:

method join(List:D: Str(Cool) $separator = '') is nodal

It is clearly seen that when invoking the method with no arguments, the default separator is an empty string, which is exactly what we need for passwords. (Learn more about the is nodal trait in the documentation; it is said there that the trait is not supposed to be widely used in common code.)

You may also ask a question: What characters can I expect in the password? Great that you ask! Perl 6 is a Unicode-oriented language, and the range '0'..'z' seems to contain characters with different Unicode properties (i. e., digits and letters at least). To see what’s inside, just remove the pick method from our today’s code:

('0'..'z').join.say

This line prints the subset of the ASCII table between the two given characters: