Raku Quiz
At the latest German Perl Workshop I held a 40 min beginner- to mid level talk about Raku. It was about the habits of Perl programmers that turn contra productive in this new language. This article is a summarizing recapitulation of the pitfalls minus the intro about the history of Raku, the zef ecosystem and some general knowledge - for all those who could not attend or don't speak German.
My first code related slide showed:
use v6.c;
To revamp on the Raku versioning system but also to point out if you leave out the ".c" its actually like in Perl and would get an almost proper error message from Perl - but since the name change to Raku und having the file ending .raku .rakumod and .rakutest this once good idea lived out its usefulness.
Spacing
The first point I hammered over and over into the listeners brains was: watch out your spacing. For instance
my($ö) = 3.;
Will come back and bite you since there is no sub declared with the name my. There has to be one space after any keyword unless its unambiguous (by using a sigil e.g.). But in this case the braces could envelope a signature. To make things interesting I put feints and multiple errors into the examples. So unlike in Perl, the ö is no problem. Raku works like use utf8; is always on. But the number is illegal. You can write .5 but dangling dot is not allowed, since it could be also a dangling method call since 3 is an object from type Int. I showed this by telling about 3.WHAT and $ö.WHAT, which is "(Int)" and I had to explain the difference between value types and container types. Since $ö is not a type bound container it behaves like in Perl an may receive a string afterward. So the best way to write this example is: my $ö = 3; To level up the spice i chose the next example:
OO everywhere
my $ß' = Int->new();
And surprisingly I caught most of the audience with this blatant error. Method call is ofc the dot and not -> like in Perl but the power of customs did bite here. But the Raku compiler complains about something else first: Variable names may include an apostrophe or an hyphen, but not on the end. So this example has to be fixed into: my $ß's = Int.new(); Just to reiterate, Raku has not only types - there are types all over to the bottom all types are Objects. Even the Classes are Objects (MOP). So $ö = 3; was just a neat way to say $ö = Int.new( 3 ); . And since types have default values the Klingon variable $ß's has the content of 0, hence its defined. After explaining that $ß's.DEFINITE is just another way to ask for defined - ness and that Int:D is not the funny sister of Int but something that enforces defined - ness we got ready for the next example.
my Int $z = Inf;
Perl would not object, but Raku does, since Inf is of type Num, not Int. Floating point numbers can be infinite but an Int just grows into what would be in Perl a bigint and in Raku is a normal Int with an irregular hunger for memory and CPU. Another pit for Raku newbs.
@a.push 7;
Doesn't feel quit right and it isn't. If you want to leave out the comma, use the braces or double colon : @a.push: 7;
$n<1;
This was reminder: watch your spaces. <> is the new qw// and also used for quoted hash slices so Raku had no way of knowing if this is an syntax error and you meant $n<1>. Which is a discussion that needed the side track to mention that there are no longer "references". A Hash container object be equally held my $h and %h.
if $a < 0 { ... }
This was a feint, no error and yes $a is no longer special. And it was a reminder round braces are optional in Raku and this is the native way to write an if statement. The I explained the new ternary op: 1 ?? 2 !! 3 which is way better visible inside larger statements and is consistent with the other ops since its more in line with other short circuit op like || and && and ? and ! are the general signs for yes and no in Raku language. It was not much of a pit since the error message was very clear and Raku just tells you: you used ? : of you meant to write ?? !! since this is the ternary op. Raku is quite good at this at some spots.
^Iterate!
for (my$i=0;$i <5;$i++) { say $i }
Yes C - style loop is still around but its spelled loop since while and until enforce boolean context, for like an comma creates a list it can iterate over and loop is neutral here enforcing no context. And besides, loop { ... } is a cleaner way to get and infinite loop and less of an (established) crutch than while (1) {}. Of course we in Perl (and Raku ?) would never use that but instead:
for (0 .. 4) { say }
Which was a great opportunity to explain yes there is still $, one of the four surviving special vars (@, $, $/ and $!) but it doesn't will be automagically inserted into @. Instead of you write for (0 .. 4) { .say } which is short for for (0 .. 4) { $.say } and there is always for (0 .. 4) { say $ }. But since I wanted teach native Raku - the way to go is: for 0 .. 4 -> $i { say $i }. The short arrow op does create a real ad hoc signature and can be used everywhere, no more special rules and with <-> $i becomes a writable variable. But there was still more honey in this example to suck, since you could compress it to: for ^5 -> $i { say $i }. So I had to explain that ^ is in Raku the ordinary way to exclude the bounds in ranges. So Raku knew this is a Range. Since ^ was to the left of the number it was the upper bound, so Raku filled in the default lower bound of zero and in list context (enforced by for) you get: 0,1,2,3,4 to iterate over. I mean how often you found annoying to write for my $i (0 .. $limit-1) { .... Its also these little things than make programming Raku refreshing just by typing for ^$limit -> $i { ..... Plus we got just another way to write if 0 <= $length < 5 { ... , it's: if $length ~~ 0 .. ^5 { ...
While on the topic of iteration I had to also point out how unclean inner workings of the the keyword each is in Perl and how much better the solution in Raku. Either you get from an hash in list context a list of pairs:
for %hash -> $pair { say $pair.key }
or you
for %hash.kv -> $key, $value { ... }
Raku has no longer autoflattening of list which is source of many surprises for seasoned Perl programmers (this is a list with 3 elements: (1,2,(3,4))). It is also to consider when iterating over cross products:
for @l1 X @l2 -> $tupel { ... }
What to say and what to put
The next pit was very unexpected one. Since everything is an object you can convert it into a String by calling on it .Str or into a string representation that could be evaluated back into same data structure with .Raku. But even more often you need .gist which gives you a nice overview and stops for instances to spill out the Array content after 100 elements. Objects like IO handles give a much nicer summary about their status is you call .gist than if you just call .Str (which is equivalent for using them in String context). And because .gist is what you want in most cases it gets silently called when using say. If you don't like that, you have to revert to print - or if you want to avoid typing "/n": use put. Yes its all laid out nicely in the documentation but still - as a newb search the bits you think you need.
What goes in and what goes out
The last chapter was about IO since its an integral part of working with Perl (and Raku). All the functionality is classes in the IO::* namespace, including the whole pathtools, cwd and more. (Raku went the batteries included route). And we have an .IO method to transmute a string into a dir or file handle. So -e "filepath" in Perl becomes "path".IO.e which I personally like more than the prominently touted "path".IO ~~ :e which does the same. slurp and spurt are of course a huge winner in beginner tutorials since its reading and writing files without any handle. Just directly from file name to string content:
my $text = slurp "filepath"; # but :
my $text = 'datei'.IO.slurp;
And you can even iterate over lines of a text file and even directories without any handle. My last example demonstrated all that.
for '/path'.IO.dir.grep: {.f} -> $file {
say '== ' ~ $file;
for $file.lines.kv -> $nr , $line {
say " $nr : $line";
}
}
P.S. Don't worry all the seek and tell stuff is till there.
Leave a comment