My path to becoming a Rustacean
The future is Rusty š¦#
āIt wasnāt always so clear, but the Rust programming language is fundamentally about empowerment: no matter what kind of code you are writing now, Rust empowers you to reach farther, to program with confidence in a wider variety of domains than you did before.ā
ā The Rust Book, foreword
The quote above is easy to gloss over when first reading the Rust Book, but itās a powerful statement that Iāve come to appreciate more and more as Iāve spent time learning Rust this year.
Iām a long-time Python developer who always struggled with C and C++, from a syntax and a usability perspective . For the most part, Iāve avoided thinking about lower-level concepts like memory management and static typing and gotten away with it, because there have always been excellent Python libraries that do a lot of the heavy lifting from a performance perspective.
However, in recent years, as Iāve become a more experienced developer tackling ever more complex problems, the need for a different style of programming with compile-time checking has become that much more apparent in my work.
In this post, Iāll highlight my learning journey with Rust, and how Iāve come to appreciate the language and its community. Iāll also share some tips and resources on how you can get started and most importantly, stay motivated in your journey.
A list of Rust learning resources thatās greatly helped me in my journey is available at the end of this post.
Why I need more than Python#
Python has withstood the test of time, and Iāve enjoyed using it (for the most part) for numerical/scientific computing, data science and machine learning tasks over the last decade. Itās really easy to get started with, and there are a ton of great libraries out there that make it easy for relatively inexperienced programmers to build complex applications. However, itās in Pythonās very strengths that there lie footguns that could lead to problems down the line.
TL;DR
The issues listed below are not related to Python (supposedly) being slow. In fact, itās relatively easy these days to write performant Python code, via itās amazing library ecosystem, thatās fast enough for most use cases. The key areas of interest for me are related to safety (primarily type safety), and reliability of code that runs in production.
Python discovers bugs at run time#
Python is a dynamically typed, interpreted language, which means that the type of a variable is inferred at runtime. This is great for getting something up and running quickly, but it also means that your initial runs in production will almost always error out, due to bugs that can only be discovered at run time depending on the existing environment. This leads to a frustrating developer experience, and worse, some of these bugs can be incredibly hard to track down in a large codebase.
In a recent Python project, I spent 3 days tracking down a bug (with unhelpful error messages) that I painstakingly discovered was related to an invalid datetime object. This is a rather trivial bug that would have been caught at compile time in a statically typed language.
Rust is a statically typed, compiled language that greatly emphasizes type safety. The Rust compiler is famously strict, and can catch whole classes of bugs prior to run time. In my early days using Rust, Iāve found that the compiler is (mostly) helpful via its error messages, though there are definitely still situations where I canāt make head or tail of the error messages ā this will hopefully improve with time.
Python type annotations can be a mess#
The original intention behind Python type annotations, or more simply, typing, was to help developers catch type-related bugs early on via static type checking (like mypy), and to help with code readability. However, as the docs state, the Python runtime doesnāt enforce types ā code that has invalid type annotations will still run perfectly fine ā typing is a voluntary exercise by the developer, which doesnāt exactly help increase oneās confidence in the code itself.
In practice, type annotations can be a mess from a readability perspective, while still not eliminating type-related bugs entirely, especially when youāre dealing with the complex data structures commonly seen in production-scale projects.
Rust has an immensely powerful and expressive type system, now with an entire team dedicated to supporting it. Itās relatively easy in Rust to define complex, custom data structures that make code easier to read and understand. The compiler is very helpful in catching type-related bugs early on, avoiding a lot of developer frustration prior to running any code in production.
Refactoring can be a nightmare in Python#
When refactoring even a moderately large codebase in Python, itās all too easy to miss edge cases and lose faith in your existing tests due to relatively trivial bugs that surface in production. Although the availability of static type checkers in Python have reduced the need to write certain kinds of tests (which is a good thing), type-checking in Python isnāt enforced by the interpreter ā so itās still very common to face all sorts of nasty bugs in production following a major refactor.
Rustās strict compiler can be frustrating for newcomers to the language, but it really helps with catching entire classes of bugs prior to run time. This means that you can focus on testing mainly for logical bugs, allowing the rich type system and compiler checks to assist you in other areas. Refactoring a large code base in Rust (Iād imagine), is a far more pleasant task than in Python.
A learning path for new Rustaceans#
Iāve been learning about Rust for the past year, and, like many others, Iāve found it to be a very different language from what Iām used to. When learning a new programming language, conventional wisdom states that you go ābottom-upā, starting with the fundamental concepts and building up from there ā this is typically done via books and tutorials. Alternatively, a lot of folks choose to begin ātop-downā, starting with a high-level overview of a problem of interest and then diving into the details that are relevant to that problem, by directly working with code and examples.
Personally, Iāve found that the best way to learn Rust is to approach it from both directions at the same time, i.e., alternate between the bottom-up and top-down approaches when youāre starting off. This is because Rust has a lot of concepts that are hard for beginners, like traits, references, borrowing and lifetimes, but these concepts are ubiquitous throughout the language, in a way that you canāt sequentially increase the complexity of your learning without getting stuck.
Start by reading The Rust Book cover to cover and then go through some pre-built exercises (like Rustlings). Itās okay if it all doesnāt make sense in the beginning ā the primary goal should be to get a sense of the terminologies used in Rust, and to get a feel for the languageās syntax and structure.
The following subsections will go into more detail on the steps I followed that were very helpful to a) get motivated and b) remain motivated to continue learning even when the going got tough.
1. Consume all the content#
I had a lot of fun this year reading blog posts, watching YouTube videos, listening to podcasts and simply following other Rustaceans on Twitter, giving me a very clear drive and focus towards wanting to go deeper on my own terms. Just like with any other language, I believe the best way to learn Rust is to consume as much content on it as you can to gain a birds-eye view of useful features, and to then try and apply it to your own problems.
Keep alternating between the various forms of learning material, allowing your brain to process the information in different forms. Over time, you get hooked, and the pieces start to come together in your mind. There are so many great learning resources out there, which I list at the end of this article.
2. Describe in words what makes Rust great for you#
Ask yourself the question: Why am I interested in learning Rust? If the answer is ābecause everyone else is talking about itā, or anything else related to FOMO, youāre probably not going to get very far. The key is to convince yourself of what aspects of Rust resonate with you. Depending on your technical background and career interests, your answer could be vastly different from mine.
In my case, it was the exact reasons I listed above and my frustrations with Pythonās type system (or lack thereof), that led me to discover Rust. Having consumed my fair share of podcasts, YouTube videos, blogs and books over the course of a year, Iād learned a great deal about Rustās expressive type system, strong emphasis on safety and what having good compiler checks can do in terms of catching bugs early on.
3. Embrace the memes#
Learning is also about having fun ā when the going gets tough, the best way to keep at it is by laughing at yourself and the situation youāre in. @shuttle_dev has among the strongest meme games out there, not to mention that they regularly post great learning material as well. š
Twitter and Reddit are also great places to find self-deprecating content and memes on Rust, and the Rust community in general is very welcoming to newcomers. š
4. Apply Rust to your existing problems#
Donāt just follow along with what the books or tutorials show ā thatās the fastest path to boredom. Try applying Rust to existing problems that you already know how to solve in your primary language of choice.
In my case, Iām actively working on small, self-contained projects that I have no difficulty doing in Python, but am now writing from scratch in Rust. Because I already have a mental map of how Iād solve the existing problem logically, I can focus my time and energy on learning Rust terminology and syntax, rather than getting bogged down by the problem itself.
5. Document your learning journey publicly#
Donāt build and experiment in private ā in my experience, this just leads to dead ends and falling off the wagon entirely. Although it may seem intimidating at first, documenting your code and writing about your work publicly really helps with accountability. It can also help others who are in the same boat (or those who are just starting off).
Just like Iāve done in this article, Iām making it a point to write in detail about my learning journey whenever I can. Iām also sharing my code on GitHub and will soon be writing a book tutorial series that Iām calling Rust in Pieces. The project aims to document like-for-like Python and Rust code that perform the same tasks, to highlight the differences in code structure and to help gain familiarity with the āRust wayā of doing things.
Consider a simple Python function that converts unicode text to ASCII:
import unicodedata
def convert_unicode_to_ascii(text: str) -> str:
# Normalize unicode text NFKD form, then to ASCII
text = unicodedata.normalize("NFKD", text)
text_ascii = text.encode("ASCII", "ignore").decode("utf-8")
return text_ascii
In many cases, Rust code appears more functional than the equivalent Python code, giving me that pleasant feeling that Iām learning a new way of thinking about coding.
use unicode_normalization::UnicodeNormalization;
fn convert_unicode_to_ascii(s: &str) -> String {
// Normalize unicode text NFKD form, then to ASCII
s.nfkd().filter(|c| c.is_ascii()).collect::<String>()
}
As you move forward inch by inch, youāll find you are slowly but surely writing more idiomatic Rust code (with the compilerās help, of course), while also learning about the languageās standard library and the amazing crates.io ecosystem.
6. Spread the word#
Once you have a handle on the core concepts, youāll find yourself naturally thinking about your code in a way that encapsulates the Rust way of doing things ā performance, safety and low resource utilization. Before you know it, youāll find yourself evangelizing Rust to your friends and colleagues, not to mention youāll be posting about your work publicly and potentially collaborating on bigger projects with like-minded people.
Rust isnāt hard, itās just different#
No matter what language youāre coming from (or, even if this is your first exposure to a programming language), the best way to approach Rust is to think of it as a language thatās different from what youāre used to, rather than a language thatās hard in and of itself. Rust is a big and feature-rich language whose core concepts can take time and effort to grasp, but there are plenty of resources out there to learn it over a sustained period.
Iād argue that writing Rust makes me a better Python programmer, as I find myself thinking about my codeās structure much more carefully than I would if I were haphazardly prototyping in a dynamically typed language. In Rust, you pay a cost upfront to write safer and correct code, which in turn makes you think about your codeās structure and design from the get-go.
Although the initial āhoneymoonā period will come to an end and you might hit a wall with concepts like ownership, borrowing, traits and lifetimes, these are all part of what makes Rust so powerful. The beauty of Rust is in the fact that the parts that are hard, need to be, because they deal with core aspects of computing right down to the machine level, whereas the parts that are easy (like managing dependencies and distributing your code) are truly a breeze because theyāve been so well designed from the ground up.
A key stage in your Rust journey is when you stop feeling frustrated with the compiler, but instead start viewing it as your ally. The compiler exists to help you write better code. You spend your valuable time working with logical issues rather than the mundane, allowing you to solve problems of greater complexity with the confidence that your code is safe and will run reliably in production.
Is Rust the perfect language? No, but no language really is. There will most definitely be periods early on in the journey where you donāt feel as productive as you did in your erstwhile favourite language, but here, The Rust Book is forever your friend, and youāll find yourself re-reading the book multiple times as you pick up on things you missed the first time around.
Conclusions#
For me, this is just the start of a multi-year journey learning Rust, and Iām excited to see what this ongoing wave of enthusiasm among new and established Rustaceans blossoms into over the coming years. After all, Rust is a language thatās been designed to be around for the next 40 years. Having come to Rust from Python for the safety and reliability that it offers, the speed/efficiency gains it offers are just the icing on the cake.
Itās very easy for one to feel impostor syndrome while learning Rust. Tim McNamara frames this really well: start small, and grow gradually. When youāre starting off, itās OK to write basic code that might be inefficient, as long as it works and achieves the intended goal. Chances are, your relatively naive Rust code will still be way faster than your Python code. š
When do you call yourself a Rustacean? Jon Gjengsetās take is: āYou are a Rustacean from just before the first time you ask yourself whether you might be oneā.
Having spent some serious time studying Rust this past year, Iāve come to frame it for myself as follows:
If you find yourself thinking about Rust, writing Rust code and spreading the word about it, you are a Rustacean. š
Learning materials#
This section summarizes some great learning resources Iāve come across and benefitted from in my learning path. Feel free to comment and add some more to this list so that others can benefit from them as well!
Books#
I recommend reading the following books in the order listed below:
- The Rust Book by Carol Nichols and Steve Klabnik
- Rust in Action by Tim McNamara
- Zero to Production in Rust by Luca Palmieri
- Rust for Rustaceans by Jon Gjengset
YouTube channels#
The following YouTube channels are great for tackling specific concepts in Rust, one by one, and to gain a birds-eye view of the langauage.
- Tim McNamara @timClicks
- Tristram Oaten @NoBoilerPlate
- Trevor Sullivan: @TrevorSullivan
- Jon Gjengset: @jonhoo
Podcasts#
The following podcasts are great for getting a sense of the Rust community and the people behind the language. Iāve listed individual podcast episodes from other podcasts that are also worth listening to.
- The Rustacean Station
- Are we podcast yet?
- Rust: A language for the next 40 years: Carol Nichols, Hanselminutes
- The future of safe and efficient programming: Tim McNamara, AWS Developer Podcast
- History of Rust: Ben Striegel, Rustacean Station
- Rust for Rustaceans: Jon Gjengset, Rustacean Station
Exercises/Tutorials#
- Rustlings: Small exercises to get you used to reading and writing Rust code
- Rust on Exercism: 96 exercises to help you write better Rust code
- Rust by example: Extension to the Rust Book, with examples of common Rust concepts
- Shuttle Launchpad: A series of exercises by the folks at Shuttle and Stefan Baumgartner, organizer of the biggest Rust meetup in Europe, to help you learn Rust by building a real-world applications
Blogs/Newsletters#
The following blogs cover an extensive range of topics related to Rust, and are great for keeping up with the high-level features and developments in the language.
- This Week in Rust: Links to all the latest Rust news, blog posts, RFCs, etc.
- Armin Ronacherās thoughts and writings
- Steve Klabnik blog
- Niko Matsakisā blog
- Shuttle blog: Great blog by the makers of a Rust infra-as-code framework
Have fun learning, and letās build more things in Rust! š¦