DEV Community

Lindsay Kerr
Lindsay Kerr

Posted on

Rust, I really tried to like you.

For the past few months, I have been getting familiar with Rust. It started when I felt there was a need to delve into web assembly. For whatever reason the software gods had claimed that compiling code from Rust to web assembly was a fairly painless experience. In addition to Rust being voted on Stack-overflow as the world's most-loved programming language for several years now, I thought "Why not just learn Rust!". And that's what I did. Rust, a language with one of the steepest learning curves around, just so I could add some web assembly to a web app…. Yet, while I am proud of myself, for attempting to climb a mount Kilimanjaro of a language, I left the experience feeling a bit deflated.

Gaining some experience with Rust

I started my journey down the Rust rabbit hole by creating an app. For this, I used Tauri, a framework for creating desktop apps with Rust. It was a barely passable app, you know the type that kind of works, just good enough to pass as a first iteration. That was okay, I achieved what I had set out to do and gained some hands-on experience with the language. Next, I would try building a RESTful API. Over the first few weeks, everything was going somewhat smoothly. I managed to get the GET requests part of the API working without much issue. Then my greatest achievement would come through implementing a tree-like structure which aided in validating URI resource requests. I was very proud of myself. The pride was not because I had come up with a solution, it was because I had implemented a simple tree-like structure in Rust. Honestly, what would have been easy and painless in almost any other programming language turned out to be surprisingly challenging in Rust.

And this would become a common occurrence, where I felt like I was fighting an uphill battle with the language and compiler just to get things done. For all of its claims of creating memory-safe and efficient code. I found the actual coding experience frustrating and overly time-consuming.

For or against?

So after a good few months of soldiering on, I decided to put Rust back in its box. I am glad because I have started to hate it, and I don't want to. This hate was born from my frustration and failed expectations that I would attain some sort of familiarity with the language by now. The thing is, I still admire Rust as a language. I too acknowledge that Rust does seem to be superior in some respects to other languages, especially concerning memory safety. It has performance comparable to C/C++ on certain tasks. Yet the great benefits that Rust provides, I believe negatively impact the language in certain areas, mainly expressiveness and flexibility.

Observe

To give an example, I thought I would try to implement the Observer pattern in Rust. One of the operations in the observer pattern is to remove an observer object from a Subject's collection of registered observers. The implementation will usually involve some sort of comparison check to find the observer to be removed, often a pointer-like mechanism provided by the programming language is needed here. Rust dissuades the use of raw pointers and so provides things like Box and other such specialised structures/types that enable memory-safe-like pointer functionality. These are straightforward to use on simple structs and types, but if we are working with objects that implement the same "trait" (Rusts version of an interface) then we need some sort of dynamic memory allocation because the compiler has no idea of an objects size that implements the trait. Rust has this covered with the keyword "dyn" which triggers Rust to dynamically allocate memory on those objects. So, I have cleared one hurdle. Now I must tackle the test for equality. Rust's Box type can test for equality on non-dynamically allocated objects without issue using the eq function. This eq function derives from a PartialEq trait. Yet, as I have stated I have to deal with these dynamic trait objects. The solution is to implement the eq function by adding the PartialEq trait to the Observer trait and provide my implementation of eq to test with equality. The implementation of the eq function below was spewed out by Copilot, which I believe is using raw pointers... so much for the need in avoiding raw pointers then.

impl PartialEq for dyn Observer {

    fn eq(&self, other: &Self) -> bool {
        self as *const _ == other as *const _
    }

}
Enter fullscreen mode Exit fullscreen mode

And so I find myself in a state of "Oh, but wait, how do I... another error!... I got this working but why?... another error?"

Later I decide to carry out the same exercise using modern C++ and I achieve what I set out to do, quickly and without much effort at all.

The elephant in the room

As I see it, it will take me a very long time to achieve proficiency in Rust. I classify proficiency as having such a grasp of a language to such a degree that I can effortlessly apply it to software problems without much effort. Competency on the other hand is a case of having just enough familiarity and confidence with a language that work can get done. Rust by its design enables competent developers to almost guarantee solid, fast, safe and effective solutions. It is also by its design, that we programmers have to shift from worrying about pointers, memory allocation and memory leaks to spending time worrying about ownership, borrowing and lifetimes. A new set of headaches simply replaced the old ones. Not only that but there is a whole shift in the coding workflow paradigm that takes place, such as being aware of patterns, unpacking and packing values, using enums as types, etc. I believe it can take many months to get settled into Rust's rhythm.

If I were to give an honest estimate regarding how long it would have taken me to become competent (not proficient) in using Rust from the very start, I would estimate anywhere between 6 months to a year. While with C++ maybe one to three months, not including the build system. So I could likely add myself to the ranks of 30.3% of respondents from a 2018 Rust survey stating that they only felt productive using rust in less than a year. Interestingly I have noticed the more recent survey avoids drawing attention to the time it takes to become productive.

So if I keep on working with Rust, to gain that competence with the language, do I think the time and investment spent on it would pay off in the long run? Well, I don't believe so. Not at this stage in my career.

Avocados

I honestly thought the more I used the language, the more I would fall in love with it, as advertised, but that has not been the case. The more I have used it, the more my frustration towards it has grown and conversely so has my appreciation for other languages. In this, I have provided a subjective opinion on the language, but there are plenty of individuals whose views move in the opposite direction to mine. Some of them have used C/C++ for years hated it, tried Rust, something clicked and they fell in love with it. With that being said I hate Avocados, everyone I know loves them but there is something about the texture I don't like. I suppose for me Rust is my programming language equivalent to an Avocado.

Top comments (0)