There’s been an awful lot of talk about Rust lately, and I’m not talking about that reddish crap that eats away at your car bumper. I’m talking about the programming language that’s been voted “most loved” by Stack Overflow for the past three years. In an age where programming languages come and go, it is incredibly difficult to determine what is simply “the new hotness”, vs what is going to stick around for a while. I mean, for Pete’s sake, I have counted almost 700 programming languages in existence. Why in the world would anyone pay any attention to this new kid on the block.
There’s been a bit of a push, lately, in compiled languages (e.g., languages that compile into native code, such as C++). Compiled languages generate machine code that runs directly on the CPU. The result is that a program that runs faster and has access to lower-level OS and hardware features, but usually at the expense of readability, maintainability, portability, and/or security. There have been two languages developed recently that stand out as contenders to bring native compilation to applications in a safe and secure manner without having to sacrifice those ‘ilities you had to in the past: Rust and Go.
I decided to dive a little bit deeper into Rust to see what the hubbub was all about.
Rust Is A Functional Programming Language
Don’t let it fool you. If you buy into Rust because it offers security, efficiency, and speed, that’s not all you’re going to get. You’ll also be investing in one of the most impressive functional programming languages that I’ve seen. The idea of functional programming has been around for a long time, but if you’ve never weighed the benefits and consequences of functional programming over other methodologies, you are missing out.
What exactly does Rust do to lend itself so nicely to functional programming?
- For starters, everything is immutable by default. Side-effect free functions are paramount to functional programming.
- The Option type is built into the language. This, in and of itself, is enough to squash the billion-dollar mistake. Granted, if you don’t know how to correctly use the Option type, your code will be littered with hundreds of little unwrap() statements. Yes, you should be very ashamed.
- The Result type is also built into the language, which is a game-changer when it comes to exception handling. Through type safety, you are forced to handle both success and failure conditions, thereby eliminating a large number of bad assumptions.
- Tuples, structuring, and destructuring are built into Rust. This allows you to transfer information between methods without having to create a large number of superfluous, intermediate data types.
- Rust supports lambda expressions (e.g., closures), which can be used to construct higher-order functions.
- The Rust type system separates interface and implementation with trait and impl, respectively. However, you can implement any trait on any type. There is power in this, as it lets you add methods to types for which you have no control, similar to extension methods in C# or monkey patching in Ruby. Again, this is huge for functional programming.
- The pattern matching supported by Rust is powerful and concise.
There Are Niceties for Everyone
There are a number of features that are icing on the cake for most programmers.
- The compile-time type inference makes defining variables much easier. To me, it feels a bit like writing type-safe native code with TypeScript.
- There are no pre- or post- increment/decrement operators. Say goodbye to ++ and –. I’m not even sorry if this offends you. If I could tell you the horror stories I’ve had to endure from these operators.
- The language is surprisingly terse. I’m not usually a fan of abbreviations in either code or programming languages, but the Rust team has made everything so consistent that the abbreviations are natural and actually make sense.
And Yet, There Are a Few Things I’m Weird-ed Out About
It never ceases to amaze me. Every time I get my hands on a new technology, I’ll plow through the documentation and everything makes sense. Well, until it doesn’t. I had several double-take moments that forced me to ask the question, “Why the blankety blank did they do it that way?”
- For newbies, the range operators are begging for off-by-one errors. I understand that the exclusive operators are very useful when using for loops, as you can simply provide the length as the upper bound, but this is still begging for typos. Part of my problem was that the syntax was in flux until version 1.26, but the fact that the exclusive range operator takes less typing is going to prove to be confusing for some victim…er developer.
- The lack of a return statement for a function is awkward. Simply omitting a semicolon makes it a return statement? This is just asking for trouble.
And There Are Things I’m Still Not Sure About
For the most part, I do like what I see in the language, but there are still a few things that I’m on the fence about.
- I’ve never really been a fan of documentation in comments. I know that it is a huge gain for developers that are consuming third-party components. But for developing in-house applications, this documentation quickly becomes burdensome and stale. With that said, Rust’s built-in support for documentation offers some advantages to prevent comments from becoming stale. First, the comments use markdown format, which greatly simplifies the documentation. Secondly, the examples that are included must be valid code that is compiled by the Rust compiler. This forces the examples to be kept up to date. Still, whether they are or not will be determined in the future.
What do you think of Rust? Have you had success in implementing enterprise applications with it?