I've been poking around with Hare to kick the tires and see how the language is shaping up while it is still in heavy development. Here I note a few things I have found surprisingly pleasant.
I have something of a problem with programming languages. I can't not look into each and every one. Never mind the fact that TCL went out of fashion decades ago or that people think J looks like line noise; if you write a programming language I will at least read the documentation to get a feel for it. Unfortunately with Hare being so early in development there is a dearth of documentation outside of the tutorial.
For larger projects and more complex languages this may have been a sufficiently high barrier to make me put off looking any further. In the case of Hare though I found the language simple enough with logical choices (like making the language expression-oriented!) that I found reading the standard library etc. enough to give me a feel for things.
I will admit, I am willing to give Hare a chance so early in development because it is one of Drew DeVault's projects and I've enjoyed contributing fixes to his projects in the past. It turns out Hare is no different. When I saw the release announcement I browsed through the bug tracker and saw a few things I figured I could fix. In a few hours I had picked up a ticket I was interested in, learned enough of the language to make a fix, added tests and sent a patch. Then I made another.
How many projects - open-source, proprietary or other can boast such an easy on-ramp?
While I have seen QBE mentioned before, probably in the context of cproc, I haven't given it much thought. Hare has changed that for me because of how small everything is. The Hare compiler is a front-end concerned with an intentionally small language leveraging a tiny back-end to generate efficient code. It works really, really well. If you have ever tried to go spelunking through LLVM or GCC you probably know what a nightmare any single trace ends up like. Hare and QBE are the exact opposite. It isn't that they aren't clever, they end up clever where it seems to matter. It is as though the 80/20 principle was distilled in a secret lab somewhere.
It may be that Hare gets this next one for free but it is a big one for me, personally. I don't need to find or learn many new tools to develop within it. My first patch to the standard library was to fix an issue with uninitialized memory flagged by Valgrind. I've used Valgrind before, I can work out how to fix whatever it is telling me. I have not used it as much but GDB seems to work with approximately as much effort. Having experienced the opposite with languages like Go, Hare is a breath of fresh air.
This is probably a matter of taste but the way Hare integrates
tests within the source file reminds me of Racket's integrated
test submodules. I think the style is becoming more prevalent
(I'm pretty sure I've seen it in the wild with
Zig). It
makes my own preferred development style really ergonomic,
looking for call-sites and examples when making changes is just
using your editor's search function (or grep
).
I read about
the twenty
year anniversary of Valgrind this week and have been
thinking about how I might use it more. An opportunity presented
itself today when I tentatively started
re-writing some
C code in Hare. I had a small program that ran but was
hideously slow, rather than overthink things I thought I might
see if Valgrind could make any sense of a compiled Hare
program. It turns out it can without any work, I just
invoked valgrind --tool=callgrind my-program
and it
just worked. I spent maybe two minutes looking at just the
number of calls per-function and realized my problem — Hare's
regular expressions are POSIX extended regular expressions and
thus don't have the option for non-greedy matches so something
like <h1>(.*)</h1>
will give a pretty
sweet example
of Shlemiel
the painter's algorithm. The fix is to either add something
like <h1>(.[^/]*)</h1>
or the correct
thing and give up on using regular expressions). I was able to
confirm my intuition partly because the regular expression
library
is very
straight-forward.
I like it! While I don't have too many projects that need a systems programming language I see the appeal in this one. It feels very much like something which you can understand the entirety of. Reading about using io_uring within Hare was a nice read not because it demonstrates any great feat of the language but because it gets out of the way. My sense of Hare so far is that you can learn it and then get to work (probably with a copy of The Linux Programming Interface handy). For me personally that vision appeals greatly after spending so much of my life chasing down package conflicts and bugs in third-party libraries.