Abandoning the Rust Programming Language

posted in Moonlight coffee
Published September 26, 2024
Advertisement

This is my second “abandoning” article (also see “Abandoning Vulkan”) so it needs to be mentioned that I am all for trying new things and not sticking to a single programming language or technology in general. As was the case with the Vulkan API, before deciding to write this text as the conclusion of my relationship with Rust, I consider that I have spent a fair amount of time with it to be able to form an opinion. Beyond reading the whole Rust book and playing around with examples and code snippets, I have spent hours on a couple of Rust projects, one of them published on GitHub.

How I got involved with Rust

Before discussing the reasons that have made me drop Rust, I think I should also mention what got me to learn it in the first place. I first heard of Rust through mentions by other C/C++ developers, either in their blogs or during discussions. Already ten years ago, there seemed to be this tendency in parts of the C/C++ world to at least pay lip service to it. Some would mention during a conversation that it is the compiled language of the future or post in an article or on their profile that they are doing something along the lines of “keeping Rust on the back burner”.

Flash forward to a couple of years ago. By then dedicated de-complexed Rust developers had become somewhat more numerous. Also, a friend of mine told me that he had accepted a job for which he would learn Rust and use it on a project. I got motivated to take a look. I started learning it during my free time. I usually study a programming language by combining reading with some sort of pet project, so as part of the process I started Clunker. It is a cross-platform program that renders a 3D model on the screen using Vulkan. My hope was to slowly evolve it towards it actually becoming a game or game library.

I like to think that I am a pretty good learner but I have to admit that after a few months of effort I got a little tired. So I wrapped up the project by ensuring it can at least render a rectangle on the screen on Windows, Linux and MacOS and called it a day. I thought I had seen enough for a first contact and I did not want to spend more time on Rust. I preferred continuing to work on my C++ small3d library.

Last spring my interest in Rust got rekindled. The reason was nothing too strategic or intellectual, just the frequent news of how Rust was progressing in Linux, the potential regulatory advantages it might enjoy in the future and a nagging thought that maybe focusing more on it would make me more efficient at writing bug-free games.

I enjoyed Rust more during my second go. I found it quite easy compared to last year; maybe things had “sunk in” my head in the meantime. I understood more about the borrow-checker, safe versus unsafe blocks, lifetimes, pointers and, what I am mostly interested in, its interaction with the outside world like the operating system and C libraries. I have the impression that I am decently productive in it now.

During this second tour, I got Clunker to load an entire model from a gltf file and render it on the screen, even with a bit of shading. It started looking like it is possible to actually reimplement my entire small3d library in Rust. Indeed Clunker could have someday become the next small3d. But, as you probably suspect, at this stage I do not believe that is happening in the foreseeable future.

Why I am stopping to use Rust

There are a few reasons for this and they do not have much to do with the recent Linux debacle, the C++ empire striking back with one or two ideas about safe C++, or some other dark cloud over the future of the Rust language. I think that memory safety is just one aspect of the security equation and it remains to be seen if Rust will really prove to have and edge over C++ in that domain, be that from a regulatory or a technical point of view. With regard to the success or lack thereof of Rust in Linux and other projects, it will be interesting to watch how events will affect the language’s popularity in the long-term. In any case I do not think it is necessary to always be choosing the most popular, or fashionable language. My decision to stop investing in Rust is more related to my own game development and career objectives, and my approach to organising my time.

Game development has always been a hobby for me, pursued during my spare time. I try to have fun with it and also explore domains of knowledge that can potentially feed back into my regular “corporate” development career. One implication of this is that my time for game development is pretty limited. The other is that I avoid prefabricated game engines, exactly because the knowledge gained by using them is too… gamey.

Therefore I make games mostly using code that I have developed myself, save a few libraries for image and sound manipulation and the like. This has forced me to accept certain trade-offs. My graphics are very basic and my solution for other game problems like collision detection, pathfinding or game AI are not the most elegant found in literature. In fact, sometimes I just take a shortcut and come up with algorithms which are good enough for my purposes, but which I suspect would not prove very defensible in a peer review.

Where I put a lot of effort though, is the cross-platform aspect and bug elimination. Even if my games are pretty basic, I like to be able run them everywhere and to trust that they will not crash, especially if someone has actually paid to obtain them (even if the price is a few cents). To attain these goals, a lot of time had to be spent in developing a solid layer that interacts with the various platforms and performs its tasks in a trusted manner that does not break. You might think that this is a perfect fit for Rust with its unsafe blocks and its memory safety but I think it has also been a perfect fit for C++.

With regard to writing bullet-proof code, avoiding memory bugs is just part of the equation. A lot of effort also goes into debugging logic and rendering errors and circumventing pesky hardware issues on this or that machine while maintaining the code in an understandable state that can be adapted to future conditions and needs. Working “natively” is a great asset in this struggle. I have become quite comfortable interacting with C libraries (which is what is found under the hood on a lot of operating systems) from Rust, but it is not the same as doing so with C/C++. Rust needs to know a lot of contextual information before calling a C function and the data going in and out of that function needs to be transformed and casted quite heavily. I got this covered more or less on PC machines but it makes the code more complex and hard to read. Also, integrating a Rust library on Android or iOS would require even more effort and widen even more the complexity gap between my Rust game library and my C/C++ game library, especially in the latter case because I get the impression that Apple does not care much for Rust. On the contrary, my C/C++ programs play well with Objective-C libraries since a “hybrid” compilation is possible.

I am also beginning to doubt that any comparative memory safety advantages are actually there in my Rust projects. As discussed, I interface with the surrounding environment (operating system, graphics API, etc.) a lot. This requires an extensive use of unsafe blocks. One could say that after those blocks are in place, interacting with the sound, windowing and graphics infrastructure, games can be developed on top of them in safe code. But I am wondering how different this is from interacting with the infrastructure using C calls within C++ classes and then programming the rest of a project using static variables or smart pointers.

Beyond interfacing the infrastructure, there are other elements of Rust that have given my day-to-day productivity an incorrigible hit. One is the long compilation times. I have run comparisons between the Rust and C/C++ compilers and for anything but the most basic pieces of code, the Rust compiler is slower. This affects me quite a bit because while debugging I rebuild a lot. The other thing that I find very debilitating is the debugger itself. Even with full debugging switched on, VSCode and command-line debugging always end up missing some variables. It is a huge disadvantage as compared to debugging C/C++ with Visual Studio or gdb / lldb, where one can always see everything. [2024-10-28: To be fair, this is not a valid point. I have just discovered that it was my fault because I was insisting on using the VSCode CodeLLDB extension to debug on Windows, whereas the Microsoft C/C++ extension is recommended for that platform in the documentation.]

From a long term strategic perspective, I do not see me transitioning to Rust in any way for game development. With the exception of finding a Rust job (game related or otherwise) I do not see how or why I would become a regular Rust programmer. Rewriting all my reusable game code in Rust is a no go for me. Even rewriting part of it and setting up interfaces to the rest does not seem to be a good idea. The amount of time it would take to bring Clunker at the same level as small3d, would have been humongous and Clunker is actually already referencing a Vulkan helper library I had written in C in the past (you might wonder why I have used Vulkan once again after having abandoned it years ago, but that is another story – let’s just say that I went for 100% modernity). I would need to reimplement skeletal animation, all my transformations, shadows, collision detection and the like. Add to that the new bugs that will most likely arise during development and the complexities of integrating with mobile devices as mentioned above. The conversion would be consuming my little available time for months if not years to come.

I understand that the reasons I mention for getting off the Rust bus have been discussed before. I have seen counterarguments in forums, but I have the impression that they all boil down to just trying harder and getting more comfortable with the language. There is always room for improvement but I think I have seen enough to know that my issues with Rust are real and will not evaporate just by sticking with it. I am sure that becoming a Rust developer is workable for those who are happy with the trade-offs when transitioning from another language but I am not happy with the trade-offs of transitioning to it from C++.

Why I have written this

With all this in mind one might also wonder why an article about stopping to use Rust is necessary. I do not have any precise statistics but I am getting the impression that, like me, developers feel compelled to write something about stopping to use Rust when deciding to do so (here is a better article than mine for example) and that this is more the case with Rust than with Python or Haskell for example. I think that it is a consequence of the multilateral promotion Rust happens to enjoy at this moment. With large companies and even government agencies actually suggesting that developers should drop whatever they are working on and pick up Rust, I suppose it is normal for those of us who chose not to to at least leave a little note somewhere discussing why.

How I see the future

In conclusion I am going to take the risk and express my prediction that Rust will probably not fulfil all its promised outcomes. I am guessing that it will find some domain of application, maybe even expanding what is possible to program, but it will not replace C and C++ where they are used the most. There is no perfect correspondence between the present and the past but the noise around Rust reminds me of the noise around Java in the 90s. Java was also supposed to be a leap forward, simplifying the work of software developers and taking care of memory bugs. Many were saying back then that programming in C++ or C was outdated. In the end, a lot of Java jobs were created and a lot of Java code was written, but operating systems are still not written in it and neither are most software packages we have been using and continue to use during the years. There were many reasons for this which I will not go into, but I think they are mostly related to its purported advantage, memory management and the garbage collector. It seems to me that Rust is basically promoted on the same basic premise while shifting the costs towards the development effort and compile times rather than the runtime. I personally think that this will not work as intended, but we will just have to wait and see, many years and flame-wars down the road...


1 likes 2 comments

Comments

NubDevice

Great read. 👍

Took a sniff of this rust thing just after the bio weapon release and tossed it almost immediately.

October 09, 2024 04:32 PM
dimi309

@NubDevice Thank you! I appreciate it. Also, it's good to hear from others who have reached the same conclusion. 🙂

October 10, 2024 12:02 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement