There are three points here:
- Rust lends itself to certain structures (that you might not be used to) and makes others very harder to pull off (that you might be used to). The trick is not try to do the latter when the former is perfectly fine. E.g. me trying to do object oriented programming in Rust, or starting off with a linked list as a C programmer
- Rust can be written on different levels. For example you can go for "perfect" code in terms of performance and dive into things deep or you can just not bother at all and do the totally naive thing and still end up with quite fast programs most of the time
- Rust has a type system that it strictly enforces. This makes some things harder, others simpler. Make sure to be aware what you can do with a type system and why it can be a good thing to have one.
Coming from C and PHP to JavaScript gave me similar cognitive dissonance.
Syntactically these languages are very similar, but the semantics require to rethink quite much if what I learned.
cargo clippy
Clippy won't tend to spot unnecessary Arcs and similar architectural mistakes, however it would notice if you act as though things aren't Copy when they are [e.g. you've probably never 100.clone() but if you did Clippy would point out that's just 100 and the same would apply to types where it's less obvious that they're Copy and you might have forgotten]The problems Rust attempts to tackle are fundamental problems you will encounter in many languages. Understanding how to program or how to think in order not to get those problems in the first place is the thing Rust can teach you. A lesson that any programmer can learn from.
That being said Rust has great testability and interopability. I myself use Rust in some (work) projects in conjunction with Python.
So I definitly see some future for the language, also commercially. But even if I wouldn't, I would still recommend learning it.
This is similar to the psychological trick of how an obese person, to make himself/herself feel better, stands next to an even more obese person :)
I think C++ programmers are probably the ones that are likely to find Rust easiest because they should be familiar with lifetimes even if they never really had to write them down.
- Java (compiled AOT, anyone remembers how dead slow code GCJ produced?)
- Go (not always as bad as Java, but not perfect either)Plus if one lacks the ability to write high performance Haskell code, they definitely aren't experts.
However it's not true in the specifics, there are so often little tweaks Rust has that otherwise comparable languages don't have that squeeze out a little better performance and this adds up. For example:
C++ std::vector is a perfectly respectable growable array type right? But no less than Bjarne Stroustrup observes that actually, to his apparent surprise, the reserve() method on this type isn't very effective in using what a programmer knows about the growth of a particular instance for improving upon the amortized exponential growth curve. Rust's Vec is superficially the same type. But it has a subtly different API and in the process it unlocks what Bjarne missed, using Vec::reserve() does allow programmers to successfully guide the growth curve and benefit. [[If you need the equivalent of the C++ API, Rust provides Vec::reserve_exact() for you, but you probably don't]]
Still, for a lot of us there are more important "speeds" than the performance of running code. Rust does a lot of "shift left" on errors, where more of the defects in your first attempt to solve the problem are compiler errors, which you notice quickly and can fix, rather than them failing tests, being spotted in review, or worst of all, getting all the way to an actual user where they cause real problems.
One speed that Rust doesn't have on its side is compilation performance. Rust is not going to be the fastest language for turning correct high level code into running binaries.
I noticed that `cargo check` alone is plenty fast, and when you give it a program with a type issue to check, it reports errors nearly instantaneously (< 0.5s).
So this is probably not all the type checking (including borrowchecking) that slows things down, but the phases that happen later, likely code generation. Which leads me to a question - why is code generation so slow even in debug mode compared to other compiled languages? (this is one thing that Golang does right).
Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.
There really are two distinct features and C++ specifies a single API call.
Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.
There really are two distinct features and C++ specifies a single API call.
Still, this is going way down into the weeds and very far away that any mature AOT compiled language offers good enough speed, ignoring toy compilers done by students.
(*) https://pixeldroid.com/jailang/overview/Features/Factorabili...
(**) https://www.gingerbill.org/article/2018/03/12/on-the-aesthet...*