Further thoughts on Raku pattern matching

Brains sure are funny things. Or at least mine is; maybe I shouldn't speak for the rest of you.

Last night, I posted a few thoughts on pattern matching in Raku. A bit later, I saw a reply to that post suggesting that it'd be nice to add better pattern matching syntax with a Slang. I responded by saying that it probably wouldn't require a Slang, but that I'm not typically a fan of changing basic syntax purely for convenience (when Raku already gives us so much).

I didn't give the matter much more thought, at least consciously. But my subconscious mind must have been noodling around with the idea because, somehow, I woke up this morning absolutely convinced of three things.

  1. A module should add support for better pattern matching.
  2. It could do so with a regular sub, not a Slang or term.
  3. Writing that sub would be easy.

And, for once at least, that all turned out to be true. Here's the function I came up with:

(read more)

Let's try some pattern matching

Raku has extremely strong support for pattern matching in function/method signatures – you can match on literals, types, names, or pretty much anything at all and can conveniently destructure the value you're matching on into a set of variables that fit your needs.

But Raku also has a second type of pattern matching (or at least something very much like pattern matching): the ~~ smartmatch operator powered by the .ACCEPTS method. This form of matching is also very convenient; is has a slightly different use case from matching on a signature, but it's no less powerful on the whole. And, when it fits, it can be an even better/more lightweight solution to the same set of problems. In fact, I'd bet that when (which is powered by this sort of matching) is one of the keywords that shows up most often in my Raku code.

The problem

Since these two forms of pattern matching are different, there are some problems that are easier to solve with signature matching and others that are easier to solve with smartmatching. Fortunately, Raku makes it very easy to add smartmatching into a signature – you can easily smartmatch in a where clause, for example.

I've typically found going the other direction a bit more cumbersome, however. Consider the following code:

(read more)

Raku's surprisingly good Lisp impression

Lisp is famous for having pretty much no syntax. Structure and Interpretation of Computer Programs – arguably the most well known intro to programming in Lisp – presents pretty much the entirety of the syntax in its first hour. And that's by no means the only thing SICP does in that hour.

Raku, on the other hand, has a bit more syntax.

Ok, that's an understatement. Raku is syntactically maximalist to exactly the same degree that Lisps are syntactically minimalist. Forget “syntax that fits on a postcard”; Raku's syntax struggles to fit on an A4 sheet of paper. Raku has the type of syntactic riches that inspire Rakoons to classify its operators into beautiful (though now sadly dated) Periodic Tables.

(read more)

If you want to label your code, consider Label-ing your code

When organizing a program of any size, you'll obviously need to break your code up into smaller chunks. Often, it makes sense for these chunks to be factored out into their own functions – especially if they're good candidates for reuse. But it's possible to take this urge to factor out too far and it's often a better call to leave the code inline. Doing so makes it clear that the code isn't being reused anywhere else, and keeps your program's control flow more linear.

Indeed, John Carmack wrote an influential post a few years ago describing how he has shifted from a coding style that looked a lot like

void MinorFunction1( void ) {}
void MinorFunction2( void ) {}
void MinorFunction3( void ) {}
void MajorFunction( void ) {

to one that looks more like

void MajorFunction( void ) {
        // MinorFunction1
        // MinorFunction2
        // MinorFunction3

I'm not trying to argue that this style is always better, but it is a good option to have.

When organizing my code like that, though, I don't tend to use // MinorFunction1 comments. Instead, I'm more likely to write a Label, so it'd look more like minor_function:. You might benefit from using labels too, if your language includes them – and if it's at all a C/Algol family language, it probably does. Labels are supported in at least JavaScript, C/C++, Perl, golang, and my own language of choice, Raku.

(read more)

Open Source Keyboardio Atreus Keyboard – Six Week Review

As I write this, I've now had my Keyboardio Atreus for a full six weeks and have been using it pretty much exclusively that whole time. After a month and a half, I've given it a fair shake and can give you my full impressions. And my full impression is that it is amazing.

Atreus background

Before I tell you what I love about it, what is the Atreus? Well, it's a keyboard. It's a tiny keyboard.

More specifically, it's a keyboard with 44 keys – compared with 84 on my ThinkPad keyboard, and a full 108 on a traditional desktop keyboard. How does it get by with so few keys? More on that in a minute; for now, just focus on how small the thing is, without needing to cramp any of the individual keys in the least.

The Atreus keyboard on top of a ThinkPad

(read more)

A Raku Manifesto, Part 3

In part 1 and part 2 I discussed my personal take on a Raku manifesto:

  1. Expressive code over uniform code
  2. Rewarding mastery over ease of learnability
  3. Powerful code over unsurprising code
  4. Individual productivity over large-group productivity

In those posts, I explained how Raku prioritizes each of the values on the left over each of the values on the right. I also explained that, in my view, the final value pair – prioritizing individual productivity over large-group productivity – is the most fundamental value driving Raku's design. All the other sets of priorities in my Raku manifesto play a supporting role in prioritizing individual productivity over large-group productivity. In this post, I explain why I'm convinced that Raku made the right call.

Why Raku is correct to prioritize individual productivity

I mentioned earlier that language designers have recognized the tension between individual productivity and large group productivity. If you look at what has been written on the topic – all the way from the original Programming-in-the-Large Versus Programming-in-the-Small paper through today – you might get the impression that small scale programming is a solved problem and that the only interesting/meaningful question is how we increase the productivity of large software teams. Certainly many of the programming languages that have gained popularity recently seem to reflect that view:

GolangGooglebuild large software projects
RustMozillabuild large software projects
TypeScriptMicrosoftbuild large software projects
HaskFacebookbuild large software projects

Looking at that list, you might conclude that we clearly need a programming language for large projects and that older languages do fine for smaller groups.

You might, but you shouldn't.

(read more)

A Raku Manifesto, Part 2

If you recall from part 1 in this series, we're talking about my personal take on a Raku manifesto (modeled loosely after the Agile Manifesto):

  1. Expressive code over uniform code
  2. Rewarding mastery over ease of learnability
  3. Powerful code over unsurprising code
  4. Individual productivity over large-group productivity

In part 1, I discussed how and why I believe that Raku values expressive code over uniform code and rewarding mastery over providing a fast learning curve. Now, we're ready to move on to the third value pair.

Powerful code over unsurprising code

The principle of least astonishment is a fundamental maxim of computer science that states code is far clearer when its behavior can be easily predicted; code is far more head-scratchingly confusing when it triggers spooky action at a distance.

Rust provides a particularly clear example of this principle in action: Rust doesn't let you override existing operators for existing types; it doesn't let you declare a function without fully defining the types; it doesn't let you have default arguments; it doesn't let you call a macro without using the ! character that sets that call apart from function calls. Rust is powerful enough that it could let you break any of these rules, but it doesn't – enforcing those rules keeps the language less surprising, and thus makes it much easier to reason about.

And Rust is hardly alone in this regard. Indeed, the majority of programming languages don't allow operator overloading and even fewer allow the programmer to define new operators. Put differently, most languages are willing to deny programmers the considerable power of user-defined operators to keep the language less surprising.

How Raku values unsurprising code

I've already mentioned one way Raku helps prevent nasty surprises: eliminating the action-at-a-distance variables that were so sinful in Perl 5. Raku has also thoroughly embraced lexical scoping; even when you modify Raku's very syntax, your changes will be limited to your current lexical block. And, as I mentioned in part 1, Raku strongly supports both object-oriented and functional programming – each of which, in its own way, promotes predictable code.

(read more)

A Raku Manifesto, Part 1

  1. Expressive code over uniform code
  2. Rewarding mastery over ease of learnability
  3. Powerful code over unsurprising code
  4. Individual productivity over large-group productivity

I'm not so sure that I'm a fan of agile software development (at least as it's commonly practiced). But I am sure that the Agile Manifesto got one thing really right: It not only stated what values were important but also stated which values (though important!) could be sacrificed. That is, the Agile Manifesto was explicit about what tradeoffs it was willing to make.

That's crucial because it's really easy to select some nice-sounding phrases and label them as "priorities" – who wouldn't agree that "readability counts"? But it's much harder to pick out important values that you're willing to sacrifice. And, because it's harder, it's also much more revealing. You'll often learn a lot more from knowing a project's non-goals than from knowing its goals.

In that spirit, I'd like to present a similar manifesto for the Raku programming language. Note: I said "a" manifesto, not "the" manifesto for Raku. I'm speaking only for myself; I'm sure many others would include different dichotomies on their version of a Raku manifesto. Additionally, this is very much a first draft. I've put considerable thought into this but haven't yet discussed my views broadly. I also artificially limited myself to four pairs of values (following the form set by the Agile Manifesto), and I could easily imagine changing my mind. If you disagree or just have a different perspective, I'd love to hear your thoughts on the r/rakulang thread for this post on the #raku IRC channel.

Before we get started, I want to remind you of a statement from the Agile Manifesto:

That is, while there is value in the items on the right, we value the items on the left more.

I feel the same way. All the items on the right side of the chart up above (the items that come after "over") are still really important. So, in this series of posts, I'm going to walk through the four value pairs in my Raku manifesto. I'll discuss the first two pairs in this post, and the next two in the second post. For each pair, I'll say why the value on the right side is important, and what Raku does to support it. Then I'll say why, in my view, the value on the left is even more important (for the language Raku is trying to be, anyway), and how Raku prioritizes it in ways that require sacrificing the value on the right. After discussing all four value pairs, I'll close with a post on why I believe that Raku's decision to prioritize the values on the left is absolutely the correct one.

(read more)

A deep dive into Raku's Unicode support

Yesterday, I got curious about a simple question that sent me down a bit of a rabbit hole. But now I've emerged from the hole, and want to share what I've learned. (Should that be "share the rabbits I caught"? I think I'll just drop this analogy before we end up with any dead rabbits.)

This journey will take us deep into the internals of Raku, Rakudo, Not Quite Perl, and even Moar. But don't worry – this will still be relevant to our everyday use of Raku, even if you (like me!) aren't in the habit of writing any NQP.

Here was the question: What's the cleanest way to match the alphabetic ASCII characters in a Raku regex? Simple enough, right?

My first thought was something like this:

say ‘Raku's mascot: »ö«’ ~~ m:g/<[A..Za..z]>+/;
    # OUTPUT: «(「Raku」 「s」 「mascot」)»

And that works and is admirably concise. But it suffers from (what I view as) a fatal flaw: it looks exactly like the code someone would write when they want to match all alphabetic characters but forgot that they need to handle Unicode. One rule I try to stick with is that correct code shouldn't look buggy; breaking that rule is a good way to spend time "debugging" functional code. If I did use the syntax above, I'd probably feel the need to add an explanatory comment (or break it out into a named regex).

That's all pretty minor, but it got me curious. So I decided to see what people thought on the #raku IRC channel – always a good source of advice. After some helpful comments, I wound up with this:

say ‘Raku's mascot: »ö«’ ~~ m:g/[<:ASCII> & <.alpha>]+/;
    # OUTPUT: «(「Raku」 「s」 「mascot」)»

That's a whole lot better. It's slightly longer, but much more explicit.

But – hang on! – what is that <:ASCII> character class? That's not in the docs! Is it missing from the documentation? If so, I could add it – I've been trying to do my part with updating the docs.

Well, no, it isn't missing. Raku supports querying all Unicode character properties, and you can access a large number of them in a regex using the :property_name syntax.

But I'm getting ahead of myself: this post is about the journey of figuring out the answers to three questions:

  1. What Unicode properties does Raku actually support? (spoiler: all of them, sort of)
  2. How does Raku enable its Unicode support?
  3. What additional power does this give us when writing Raku code?

So, how do we start?

(read more)

Peas in a Pod6

Maybe you already know this, but it took me way too long to realize it so I'm going to talk about it anyway: Pod is not Pod6.

I want to be clear about what I'm not saying. My point isn't that Pod6 is a different language from POD, aka Plain Ol' Documentation, the markup language used for Perl 5 documentation. That's true, of course – Pod6 and POD are not the same language – but I'm making a different point.

The point I'm making is that Pod6 and Pod aren't the same language any more that JSON and JavaScript objects are the same language. In fact, Pod6 and Pod have a relationship that is exactly analogous to JSON and JavaScript objects: like JSON, Pod6 is a notation for writing plaintext files that can be read both by humans and machines; like a JavaScript object, Pod is an in-memory representation of that content.

Put differently, Pod6 is a markup language, and Pod is a data format.

(read more)
Earlier posts →