Rust is a new-ish language that is very compelling in certain contexts, but learning it has a really deceptive learning curve, so I wanted to provide the links that I have found most effective for slow learning beginners like myself, especially because the “official” Rust book(s) are to me paradoxically hard to learn from despite being thorough.
The resources that I have found most effective for beginners, whether or not they have C++ experience, are:
- Learning Rust – nice tutorials. It seems to correctly identify ownernship, borrowing, and lifetimes as new concepts that are confusing (unrelated to anything you’ve seen before) and complex (you can’t talk about mutation without ownership/borrowing which leads into lifetimes…). This is important because it keeps the learning curve steady and gradual. Meanwhile, other Rust tutorials introduce these concepts too early without appreciating the consequences to the learning curve of the user. Or, like some Lisp resources, they introduce the concept too early because they think it’s so cool and powerful that they want to tell others as soon as possible.
- Rustlings – hands on exercises. I think things don’t sink in well without doing exercises hands on, but that is especially true for Rust. The Rustlings exercises are pretty short and self-contained while maintaining a gradual learning curve.
I think going back and forth between these two resources — reading some of the tutorials, doing the Rustling exercises — and alternating between the two until you finish them might be the best way to learn. Thereafter, you can read the official Rust Book and/or Rust By Example, but do not read them first.
An aside about language design, efficacy, and popularity
There is a lot of understandable hype around Rust, and hearing the enthusiasm of Rust users talk about it reminds me a lot about Clojure. Also, Rust introduces the concept of immutability in the language integrally in the language, and makes mutability and mutation harder to deal with than immutability, which is just like Clojure.
But eventually, I think I stumbled on an answer after remembering the comparison that Brian Goetz made in his Clojure/conj talk between what he does has a steward of the Java language and what Rich does as the creator and steward of Clojure. Goetz says Java has a very large user base, so changes have to be careful and incremental to bring along a huge percentage of the developer world towards a better style of programming away from the OOP legacy of C++ and towards the healthier paradigm of FP. He said that Clojure achieves this goal by creating a language that is unencumbered by the legacy of bringing along former C++ developers in its design, and it designs the language in the way it should be, and asks of its new users the willingness to learn and understand it. The fact that Java was designed to be a similar substitute for an already dominant language is the key. It explains the difference in popularity — as smart as programmers are, and as faithful to an objective to truth in a dichotomous true/false correct/buggy way as we think we are, programmers are subject to biases and fashions in their work, too. Java looks like C++, and most languages look like C/C++, while Lisp looks very different (which, ironically, is the source of its unique power).
It makes sense, when you think about the history of these langauges. C and C++ are languages that maintain popularity a wide reach because they allow humans the control to write fast programs that operate at low levels (OS kernels, device drivers, networking, etc.) As one person put it, C is high-level assembly. C++ gained popularity as a way to write more organized C code, and through the extra abstractions, write less overall code that is also more understandable. By pushing the OOP paradigm, C++ started with significant incidental complexity, and it continues to accrue more. Java in the early 1990s gained popularity as a substitute for C++ that has similar looking syntax but brought a simpler programming style with features that cost in performance.
Rust is a 10+ year old programming language that has steadily gained popularity over its existence by being a good C++ replacement, and even though it reduces complexity by cutting out OOP, it still is clear in its priorities that performance is above all other design goals like simplicity or developer ease whenever tradeoffs have to be made. So like Java, Rust can be seen as a nice replacement of C++, but with different priorities. Java cares about simplicity through high-level abstractions, and has a slow lurch towards Functional Programming, so it makes sense to use it for general purpose server-side applications. Rust cares about performance and uses abstractions to reduce verbosity and mental overhead, but only to the point that it can do so without impacting performance. Rust is a great choice for systems and networking programming, self-contained resource-constrained applications and libraries with few changing requirements.