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:

LanguageDeveloperPurpose
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)

Weaving Raku: semiliterate programming in a beautiful language

The other day (er, ok, month) Brian Wisti wrote an excellent blog post about tangling code using Raku.

Inverse inspiration

My first thought when reading that post was that I want exactly what it describes. My second thought, however, is that I don't – I actually want the exact inverse of what the post describes.

Brian wants to start by writing documentation and then to tangle code out of that file and into one or more executable programs. In his example, Brian starts by writing a Markdown file, and then processes it to produce multiple executable files in multiple programming languages.

On the other hand, I want to start by writing some code – specifically, some Raku code – and then to weave documentation out of that file. Like Brian, I want to write one file that both tells a story and produces machine-executable code; unlike Brian, I want to start a bit closer to the code, and generate the documentation.

Wait, isn't that just Pod6?

At first, this could sound like I'm just describing Pod6, Raku's excellent tool for writing and formatting documentation. Using Pod6, it's already easy to write clear, well-formatted documentation directly in-line with your code. And you can then render the documentation as Markdown, HTML, plain text, or any other output format you'd like. Isn't that exactly what I said I wanted?

Well, no, not exactly. A Raku file with Pod blocks is cleanly divided into documentation (everything inside Pod blocks) and code (everything outside Pod blocks). When you render output documentation, the code is ignored; when you run the code, the documentation is ignored.

This works great for many typical Pod use cases, but it doesn't really let us do the sort of thing Brian was talking about: we can't use Pod to write code and to display that code as part of our documentation. That's a little abstract, so maybe an example is in order.

(read more)

Raku testing and conditional compilation

I've been really falling in love with the Raku programming language – it's powerful, expressive, has great support for introspection, strong pattern matching, and extremely good support for metaprogramming. I'm pretty much sold on using it for any project where I don't need raw performance. (When I do need raw performance, I still reach for Rust).

That said, there are a few niceties and patterns I miss from Rust. Fortunately, Raku is powerful enough to make nearly all of them possible, usually with just a few lines of code.

Today, I'd like to talk about one example: Writing unit tests in the same file as the code under test, without any runtime cost thanks to conditional compilation.

(read more)

Cleaning your GitHub profile with a simple Bash script

I recently read Andrei Cioara's take on the best way to organize GitHub repos. The short version is that GitHub's flat name-spacing leaves all your repos in a single, jumbled list—which is both annoying for you to deal with and makes it harder for anyone else to find your most useful projects.

In particular, if you're an active participant in the open-source world, you could easily have dozens of forks cluttering up your repo list, not to mention any old, half-finished projects you might have floating around.

Andrei suggests a clever solution: Create single-user organizations and move certain repositories over to those organizations. For example, I've created a codesections-forks organization to hold all the projects I've forked to make pull requests and a codesections-playground repo to hold my one-off experiments. As a result, my main repository page is now much cleaner—down to just 13 public repos, all of which I actively maintain.

But what Andrei doesn't explain is how to move all your repos. If you do it through GitHub's UI, it's pretty painful—you have to click through several different pages and manually type in both the name of the repo you want to move and the target org. And—since the only reason this is worth doing is if you have a bunch of repos you'd like to move—this ends up being a lengthy process.

Fortunately, there is a better way.

(read more)

Screenshots from arch/stumpwm/tmux/vim/qutebrowser setup

I recently made a number of pretty significant change to the look and feel of my Linux desktop environment, and I'm pretty happy with how my setup looks now. It's not for everyone, but I thought at least some of y'all might be interested in seeing how it looks.

What I changed

I was previously using dwm as my display manager—and, if you haven't tried it, I highly recommend it. But I just switched to stumpwm, which sacrifices a bit in minimalism but makes up for it in configurability. That change deserves—and will get—it's own blog post. But, for now, you'll just get to see the pictures.

At the same time, I've changed from a standard Solarized color scheme for vim to the nofrils color scheme as part of an experiment with removing (almost) all syntax highlight from my code. That also deserves its own post; again, all you get right now is the screenshots.

The result of all of these changes is a highly minimalist, distraction-free, and keyboard-centric window setup—and I'm very happy with it for now.

Screenshots

(In each case, click for a bigger image—and most of these really need it.)

My main desktop, when I log in: screenshot of my default desktop

(read more)
Earlier posts →