Thoughts on Rust
I tend to write all my side projects in Deno TypeScript because of its simple syntax, my familiarity and background with JavaScript, and its ability to compile to a single binary. However, in a recent version of Deno, the compiler was split into a separate denort binary, making it extremely aggravating to create a reproducible compiled Deno binary in Nix[1][2]. I gave up trying, perpetually tying all my TS binaries to Deno 1.40.2.
Seeing this as the perfect opportunity to jump ship and try rewriting my programs in a cool new language, I decided on Rust, having never written a real program in Rust before[3]. Rust makes the following claims:
- memory safety without pointers
- simple yet powerful syntax
- unparalleled runtime speed
I spent the past week or two learning the basics of Rust using their official handbook, then applied my knowledge to refactor my pformat program from TypeScript to Rust. The refactor went smoothly. Here are some of my thoughts on Rust as a language:
- The syntax is surprisingly pleasant. Coming from writing a lot of JavaScript and Golang, I like when types can be inferred from context. I also like being able to create functions with tuple return types and specifying function return types in general. I also never realized how nice it is to not need to specify parenthesis around conditions in
if
statements. It's additionally very explicit in that it's very obvious when a variable is mutable or a reference. I wasn't expecting such a simple syntax from a low level language. - Library documentation is easily discoverable. The rust analyzer does an amazing job updating on-the-fly with code changes and newly added crates. Most of the time I don't need to save my Neovim buffers for the language server to give me updated diagnostics. With the crates I've used, the type definitions and hover diagnostics are thorough and always seem to provide examples.
- Ownership is nice. Rust's "ownership" approach to memory safety is a very intriguing concept that works well in most cases. It's definitely much better than having work with dangling pointers in my experience, and having these warnings at compile time means having less errors to worry about at run time.
- It's actually fast. I've heard so often how fast Rust is that I've almost been disillusioned from the idea of speed. However, Rust really lives up to its name. You can feel the speed of a Rust program. It's much faster than any language I use presently. I don't write C very often but I would imagine Rust's performance to be on par or even equal, if not better.
- Error handling could be better. I dislike Rust and Golang's "handle as you go" error handling via
Result matching
in Rust anderr != nil
in Go. It makes for really ugly code with every other line handling errors. I really hate that Rust's magical memory safety can be easily sidestepped withunwrap()
and... it seems like everyone uses it anyways. The best solution is useunwrap_or
and other utilities, but it still feels unnecessary.
If you have any questions or comments on my Rust code written for pformat
(or you'd like to tell me how to write better Rust code in the future!), feel free to email me. I have an overall net positive outlook on Rust. As with any language, it has its own unique pitfalls, but it's unexpectedly cozy. You'll definitely see me writing more Rust code in the future.
Deno downloads denort from an alternate mirror at build time. ↩︎
Deno has yet to support statically-linked binaries. There's not a huge incentive to use Deno compile without this. ↩︎
I've written a program in Rust long before this rewrite but it was a tiny program and I didn't know what I was doing back then. A lot has changed with Rust since 2017. ↩︎