Skip to content

Adventures in Rust

One of my core principles for IT research development can be summed up by a saying more than 2500 years old, attributed to Solon and appearing twice in Plutarch’s Life of Solon: “I grow old always learning many things”. In many ways, to stop learning is to stop living.

So when I need to build something I will not choose a technology or framework based upon what!s comfortable. But neither will I choose something new for the sake of choosing something new. I will consider what offers the most benefits but is also achievable. If that means stepping outside my comfort zone, if it means learning a new framework or even a new language, I’m not afraid to do so.

But I’m also a realist and results-focused. If I’m building a proof of concept and I don’t have something to show in days, it’s not an effective use of my time. The key to software development research is quick results that give a clear idea of the potential, that help identify problems or limitations, and demonstrate an approach that either can be used for a full deliverable or should be avoided. And that must never take weeks.

So having the confidence to try something new is key, but only combined with delivering rapid progress. And that’s what’s happened with a recent project. Of course I’m not going to go into minute details. This is about the “how” not the “what”, and there are still a lot of lessons worth recording.

Eating the Elephant Part One

In problem solving there’s a well-documented approach of chunking the elephant. This means breaking a problem down into smaller pieces. But the key here goes back to a blog post from last month on Shu-Ha-Ri, namely understanding how something works rather than just using it. If you understand how technologies and adjacent technologies work, if you see something as a set of steps in a process rather than a single action, you are more likely to be able to construct a similar process yourself.

And when it comes to learning a new framework or technology, you’re able to identify the parts you need to build. That was my approach and before I had even written a line of code I had a set of tasks written down for four reasons.

  1. So I didn’t forget. This was estimated as several weeks of work, providing multiple features.
  2. To allow me to place estimates against each and track.
  3. To identify how each part might potentially be achieved before a line of code was written, but also to identify what I didn’t know how to achieve.
  4. To demonstrate to others the features I expected to deliver and the approach I was taking, to manage their expectations on actual working code.

Why Rust

The proof of concept was not being built on anything else, so there was no language or framework that needed to be used. There were similar solutions that might provide a template, but none would provide sufficient code to be a starting point.

In terms of technology choices, there were two: Java and Rust. JavaScript might have achieved it and might have been chosen by someone with a strong affinity for it, but offered no obvious advantages. The choice of Rust came down to five reasons:

  1. External influences, and I won’t say more on that.
  2. Lower-level, so better performing, potentially.
  3. A colleague recommended an approach for one aspect, and that approach was most consistent with Rust.
  4. I was able to easily identify libraries that helped achieve specific requirements.
  5. If the proof of concept was replaced with anything, it would be something more adjacent to Rust than Java. There are several reasons it might stay in Rust and some it may change. But Rust was the correct choice in order for me to be productive.

Background and Assistants

So Rust was a language I have been aware of for some years, I’ve lurked in Discord chats, and did a self-paced course a couple of years ago. But no opportunity presented itself to build anything useful with Rust.

When I first learned Java in XPages, my progress was significantly improved through the help of a colleague in the open source community, Nathan T. Freeman. I had no “smartest person in the room” for Rust, but I had found GitHub Copilot helpful in code generation, explaining and fixing.

But it became apparent very quickly that I needed to undertake a refresher course. Even then, Copilot has been a considerable use. For example, the course covered Results, traits, and match. But I have not been too proud to use Copilot to fix my code to get the syntax right, and I’m not ashamed of my use of Copilot. It’s undoubtedly and significantly improved my productivity. But it’s been combined with a mindset that means I understand the code I have, I know what it’s doing, I identified where better error management needed adding and was capable of writing it. And as the project progressed I was more and more able to write running code without needing to ask Copilot.

Eating the Elephant Part Two

When it came to creating the POC, this is also where chunking the elephant proved the right approach for maximum productivity. Of course I needed configuration files, and a degree of flexibility in the functionality that increased complexity, I needed cache management across threads, and of course I need logging and unit testing. Plus there’s a layer in from of the Rust application which potentially added - and in reality did indeed add - scope for error beyond my code. But if I had tried to add all that in at the start, it would have been weeks before I had a single demo. That’s not my way and I firmly believe it would have produced messy and over-complicated code, with countless failings.

The first step was running a hard-coded piece of Rust to provide a very basic starting point. And I had that built as a demo on day one. Next was calling that from the layer in front, which again I had as a demo on day one. Functionality was added piece by piece, with the focus being multiple demos every day.

This provided two additional benefits. Firstly, regular and quick wins. These boost confidence and a feeling of progression. But they also make development fun. Secondly, if you’re adding one piece at a time or replacing one bit of hard-coded functionality with a bit of flexibility, you come up against fewer scenarios where you’re fighting with code for hours. These are the times when you become mentally exhausted and it affects not only that piece of functionality, but the ability to think clearly and effectively for the rest of the day. This results in bad code and stop development being fun.

Even though this has been a new language, and about two-and-a-half weeks of development, I’ve probably had no more than two occasions when I’ve been fighting with code and become tired. It means I have achieved immense progress which has impressed others as well as me, and achieved what I initially estimated would take twice as long. And it’s opening up wider potential than I had considered.

Conclusions

But this is a proof of concept only. It’s not guaranteed to go into a product, but nothing in the code will prevent it going into a product, if it should need to. And if it gets thrown away or put on a shelf and never used again, it’s less than three weeks work and provides a reference point for anything else where I need to use Rust. Return on investment is important to me, I value my time, and this has been another good use of my time whatever happens. It’s further boosted my confidence to achieve and it’s expanded my toolset.