Operability and Rust

Posted on 2020-12-02

Most of the discussions of programming languages focuses on development of software. Productivity of getting something up and running on one hand and maintenance costs on the other. Usually proponents of dynamic typing and interpreted languages are focused more on the speed of writing new code. The fans of static typing and compiled languages emphasize maintenance, the ability to change existing software1. This is obviously an oversimplification but in general summarizes my observations of the discussion.

My intention is not to argue about merits of one or the other approach to development but to bring attention to a different point of view of programming languages, that of operability. The best kind of operations is no operations. Operating a system should be boring. I'm sure everyone would prefer spending a weekend with friends or family to fixing broken authentication, debugging slow API response times or trying to bring an unresponsive service to life. An operable system is one which makes the job of the people tasked with running it easy, the one which works as expected both in terms of logical behaviour (correctness) and responsiveness (performance)2.

Those two values are traditionally in conflict. Picking one means sacrificing some of the other. With C/C++ (and manual memory management) for example that means achieving very high and predictable performance but accepting a risk segfaults, memory corruption and security vulnerabilities. Memory safe languages (e.g. Java, Python) do protect from those but on the other hand expose their users (and the people operating service written in them) to the complexity of garbage collection (GC), which is frequently a cause of tricky performance problems and unpleasant surprises. Languages that emphasize correctness and provide expressive type system which can be used to prevent bugs (e.g. Scala, Haskell) frequently make it easy to build constructs which are inefficient in non-obvious ways. Why an algorithm takes much more memory then expected and spending a lot of time on seemingly simple tasks is not the kind of questions you want to be answering during on-call duty.

Rust possesses some properties which make it somewhat3 uniquely attractive from the operational point of view. It aims for being memory safe without drawbacks of a GC, provides zero-cost abstractions and an expressive type system, has very explicit error handling. All those features aid building software that behaves correctly and perform predictably and consistenly. This is why I believe Rust has a lot of potential to become a de facto choice for building systems where reliability and performance are of cruicial importance, as the language stabilizes and the ecosystem matures. The additional up-front effort and a steep learning curve will pay off, considering the costs involved in the keeping the service running and evolving after it has been launched4.

1. In theory the scales of typing and ahead-of-time compilation are orthogonal but in practice they oftentimes go hand in hand.

2. I'm biased towards networked service and backend systems but the same properties are desirable in client applications as well.

3. Swift is similar in many ways while being more modest in what it's aiming to achieve.

4. Accordingly to the Google's Site Reliability Engineering book, 40 to 90% of the total costs of a system are incurrect after it has been built.