The Raku programming language

Raku, formerly Perl 6, is a programming language in the family of the Perl programming languages (the family consists on what mortals know as “perl” and “raku”). This language has influence by Perl, Haskell and Smalltalk, and have influenced Perl and Haskell. If I had to define this programming language, it would be “perl on drugs”. You could call this language “Gonzo Perl”. In this post I intend to make a brief introduction to this awesome programming language.

I am implying that if you have the most minimum desire to learn the Raku programming language, you already know a programming language. If Raku is your first language, man, you have all my respect. But I don’t think Raku is no one’s first language, so I won’t bother on explaining what an if does. Or how to print stuff. This post is serious and we are going to do actual serious stuff.

Multithreading, parallelism and concurrency

Raku has native support for Threads and async functions, there is the Thread class which allows us mortals to interact to your operating system’s thread API. This is the most primitive way of multitasking and it’s not the recommended way to do multitasking in Raku, but I’ll give an example anyways.

#!/usr/bin/rakudo
my $t1 = Thread.start(-> {say "This was printed in a separate thread"});
my $t2 = Thread.start(-> {say "Yet another thread"});
sleep(1);
say "This is printed from outside the thread";
$t1.join();
$t2.join();

So in this code snippet we are declaring 2 objects, instances of the class “Thread”, We can give it a number of attributes but the main attribute is a subroutine, which can be anonymous or not, which is what the Thread is going to do.

Programmers experienced with C might be asking where’s everything related to threads. Well, as mentioned before, the thing with Raku is that Threads is not the main way of doing parallelism, but in any case, Raku has atomic operations, locks, mutual exclusion… Following example is the usage of the Lock class

#!/usr/bin/rakudo

my $counter = 10;
my $l = Lock.new;

my $t1 = Thread.start(
     -> {
          for 1..5000 {
               $l.protect({$counter++});
          }
     }
);

my $t2 = Thread.start(
     -> {
          for 1..5000 {
               $l.protect({$counter--});
          }
     }
);
$t1.join();
$t2.join();
say $counter;

In this example, the $l is an instance of the class Lock, and we’re using to protect the critical section of the threads (when they modify a shared variable, the $counter variable).

Threads are an extremely complicated subject, humanity likes to make everything more complicated but sometimes they make things simpler, this is the case of the start and await blocks in Raku. Allowing painless parallelism:

#!/usr/bin/rakudo

my $promise = start {
     sleep(1);
     say "done doing [THING]";
     True;
}
say "Hello world!";

# Promise will wait 2 seconds and then print done doing THING,
# the program will print "Hello world!" before.

my $res = await($promise); # Wait for the promise to be fullfied.
say $res; # "True"

The start block returns a Promise object, so you can do things with it. When you’re done doing other stuff and now you need the value of the thing, you can use the await subroutine to wait for the asynchronouns block to finish and use it’s return value. The await functions can have a parameter either a single promise or an array of promises, if the case is the later, await will return an array with all the return values from all the promises on the array.

Using Perl modules

Despite it is not a design goal of Raku, raku is capable of runningn Perl5 modules using the Inline::Perl5 module. Despite the name, it does not allow calling Perl code from Raku like C code in C++. It can use clases from Perl. And converts it to Raku classes.

#!/usr/bin/rakudo

use LWP::UserAgent:from<Perl5>;

my $ua = LWP::UserAgent.new();
my $res = $ua.get("https://suragu.net");

say $res.decoded_content; # Will print this site's index.
say $ua.raku; # See how the $ua agent was initialized.

Calling C functions

This is a pain to do in Perl, it isn’t a pain in Raku as we have the NativeCall module, which makes calling C functions damn easily. So creating C libs bindings to raku shouldn’t be much of a pain.

#!/usr/bin/rakudo

use NativeCall;
# Import the puts() function form the libc. This funciton takes a
# string as parameter and returns an 32 bit integer.
sub puts(Str --> int32) is native('c',v6) {*};
# Import the write() syscall.
sub write(int32, Str , int32) is native('c',v6) {*};

puts("Hello world!");
my $str = "This will be written to stdout";
# Remember, the file descriptor of STDOUT is always 1.
write(1, $str, $str.encode.bytes);