And so it came to pass that, almost nine years since I started playing with Hylang (which eventually ran this site) and seven to eight years after I decided to move away from it into “vanilla” Python 3 and later make it static, 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.
I did it partially because I have been doing some Scheme, 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).
-> 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.
Python 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,
ifneeds to have two clauses, so I had to change a bunch of single
letreturned, 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…
require) also similarly changed structure.
niland booleans had to be translated into their Python norms.
*earmuffs*and associated symbol mapping changed, so I had to get rid of those too.
def. I nearly defined a
set!macro to make it look more natural, but decided against that and plowed on.
- Python tuples are now
#("like" "this")instead of
(, "like" "that")(also an improvement, but… annoying since
(. foo bar)is still a thing).
&restand optional argument syntax changed, as did referencing arguments (you now have
- If you’re using decorators, mind the new
(defn [dec1 dec2] function [args]...)syntax.
- Keyword handling for
:slightly "better", but, annoyingly,
dictkeys 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 LISP for me to be enjoyable (although I also enjoy Python at least as much). But Fortunately I wasn’t writing Clojure or Janet at the same time (just Scheme), 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 Scheme instead all those years back…