Syntə RSS repo @m
back

09/03/2024

The Power of Go

Let me preface this discussion by saying all this has been said before and better. Why am I bothering? Well really this post is about learning things the hard way, something I am definitely an expert at :)
But also, it may give some fresh insight to those starting out and wanting to move beyond simple tutorials.

I recently revisited and overhauled an automation script I use for work. It has been very reliable, at one point it was actually smugly correct about something that I got wrong ha. But at the same time, the code was difficult to modify or even understand! It didn’t really need much modification, more simplification, as the generalised features that I thought I needed originally, I rarely (if ever) used.
The code in question is to keep track of customers and produce PDF invoices. Sadly the repo is not public, as I don’t want to publish customer details. Nothing particularly sensitive, but I’m sure they wouldn’t appreciate me publishing their names and numbers on the internet!
There was another reason, I should confess, it was all an unholy mess under the hood…

Mmm spaghetti code

When I first cooked up this automation script, it was about all I could manage.
I was pleased enough to be able to spit out formatted invoices on demand, with incremented ‘1 of 3’ fields, current dates, and other such conveniences.
I am very much one for learning the hard way. To produce this artefact originally I steamed straight into it, grabbing at anything that worked. I knew it was messy and it certainly didn’t look like the well manicured topiary you can find in some repo’s. The code actually worked well in practice, but had reached the point where I wanted to polish it and add a couple more niceties. A rewrite, famously, is never a good option - plus the ‘business logic’ was already shaped to my needs like a worn old armchair. So the time had come to refactor it all as much as possible.

What I have learnt over time (the hard way)

When I first started out I thought functions were for avoiding repetition - they’re not. Two main purposes:

Other ‘discoveries’

I feel the elephant in the room here is that one of the authors of Go is Ken Thompson! Ok, fanboi alert… But yeah, B - the precursor to C; erm Unix - the precursor to like everything; and chuck in some UTF-8 without which where would our precious emojis be? 🤪
The language builds on decades of experience, going all the way back to Algol. Which means that there is a lot that Go does that is understated and quiet. If you let it guide you, it helps you write really clean logic. Often simply writing something more cleanly often uncovers issues that were otherwise hidden.

A good approach in general is to apply simple principles and see where it gets you. This is what I call inductive living. Let yourself be guided by paying attention to the simple details. This can feel a bit like you’re not being determined or focused enough, but it’s incredibly effective. Let the Big Picture take care of itself, while you build slowly but surely, brick by brick.

That said, I’m sure Ken would have let everyone run riot with manual memory management if he could have (or perhaps not?) The under-the-hood runtime of Go is probably most useful to enable the snazzy concurrency features. But I’m grateful not to have to remember to malloc and free things. It can also be noted that for this automation script and a lot of Go out there, channels and concurrency were not used once.
Though they have been incredible for Syntə.

Anyway,

So I set about a comprehensive revision of this atrocious code. Incrementally moving forward. Preserving - mostly - the logic. Pulling things apart, shaking down others. But it was a fun, almost relaxing task. I was able to collapse redundant code. The codebase shrank by 25%. All was all laid bare in the process. And in the end I achieved what I set out to - it is now maintainable.
I can now delve in to tweak things, add little features simply, iron out quirks. It’s still not what I’d call polished or rugged, but it’s readable.
Some of the more hairy functions have yet to be cleaned up entirely, and some larger ecumenical decisions are still lurking. But these are now much much more tractable. There is still more learning to be had too. There always is. Which is a good thing.
Go is not only a great language for writing software, but one that allows you to grow.
Syntə itself has followed a similar trajectory, which is visible in the commits.

Aaand relax…

I’m pleased to have reached a place where coding is relaxing.
This doesn’t negate my prior post because I’ve been refactoring. Which is not the same as writing.
If I was starting from scratch I would probably spec it in a very simple pseudo code and then translate into Go. Which has given me an idea… 🤔

The backend shouldn’t lead the frontend

One thing I did get right and I stand by is avoiding a ‘bumpy’ user interface - by which I mean what is natural in code does not necessarily present as natural to a human. I see this all the time in the wild. A UI where you have to go one extra step - a button press, a scroll right, or an unnecessary new page load. I hate this and one of the joys of writing my own software on this admittedly small scale, is that I can eliminate it.
And it’s all about the simple joys of life :)

↑ top