Revisiting Hy in 2023

And so it came to pass that, almost nine years since I started playing with Hylang (which eventually ) and seven to eight years after I decided to into “vanilla” 3 and later , it struck my fancy to take the old Hy codebase and refactor it to use “modern” Hy.

Getting it to a usable state took something like four hours, which I did piecemeal over a week or so in the late evenings.

But Why?

I did it partially because I have been doing some , partially because I had a few other pieces of code I wanted to refactor, and partially because having the Sushy repository just sitting there on GitHub seemingly abandoned was an itch I’ve been meaning to scratch for a while.

I don’t really give up on anything (yeah, I know, it can be a challenge), plus I needed a “half-way” project to get my mental gears going the way I wanted.

Highly Annoying Details

First of all, it should be said that Hy has had breaking changes pretty much every release. A few of them have to deal with the decision to move some of the most useful things into a separate hyrule library, but others cut a little deeper (the removal of staples like let was a big reason why I moved off it a few years back, but it didn’t stop there).

The -> threading macro and assoc (which greatly simplified a few things) were easy enough to recover, but all the other little semantic changes took a while.

has also moved on, but even though the 1:1 correspondence between the original Hy code and my current site generator has eroded, the bits that matched were still quite similar, and I could reference them when some quirky bugs surfaced.

But if you’re considering revisiting Hy after a long hiatus, let me give you a list of things I had to fix:

  • For some unfathomable reason, if needs to have two clauses, so I had to change a bunch of single if expressions to when conditionals.
  • let returned, but without delimiters between bindings: (let [one 1 two 2] ...) instead of (let [[one 1] [two 2]] ...), which is arguably an improvement, but guess how many of those I had…
  • import (and require) also similarly changed structure.
  • nil and booleans had to be translated into their norms.
  • *earmuffs* and associated symbol mapping changed, so I had to get rid of those too.
  • setv replaced def. I nearly defined a set! macro to make it look more natural, but decided against that and plowed on.
  • tuples are now #("like" "this") instead of (, "like" "that") (also an improvement, but… annoying since (. foo bar) is still a thing).
  • &rest and optional argument syntax changed, as did referencing arguments (you now have #* args and #** kwargs)
  • If you’re using decorators, mind the new (defn [dec1 dec2] function [args]...) syntax.
  • Keyword handling for kwargs became :slightly "better", but, annoyingly, dict keys can’t be used in the same way.

The Good Bits

Hy feels a lot more finished.

It is still inconsistent, the documentation lacks examples of many things and it still isn’t 1.0 (well, it was, but they backtracked that…), and there is a significant part of me that really doesn’t like the idea of writing code in a “niche” language, but truth be told that after refactoring, the vast majority of my old code worked first time.

And it still feels enough like a for me to be enjoyable (although I also enjoy at least as much). But Fortunately I wasn’t writing or at the same time (just ), otherwise things would have been weirder (especially considering I did this mostly in the dead of night before dozing off).

That said, the code now generally works and can serve a working website, although there are a few edge cases I’m squashing as I step through the test pages I (luckily) wrote almost a decade ago.

And of course it is likely to be subtly broken in multiple places I haven’t gotten to yet. For instance, I’ve apparently broken a couple of Pillow calls (every other dependency just works after upgrading them to the latest revision, which is interesting).

But regardless of whether the code is final, useful or production-worthy, it has definitely been a fun thing to revisit–although I’m rather curious about what would have happened if I had switched to instead all those years back…

This page is referenced in: