A few months ago I started learning Rust, and in the process I ended up contributing to an open source project for the first time. It turned out to be a great vehicle for learning Rust, so in this post I’d like to go over what I did and why I think it was a good learning experience. In particular I want to walk through my thought process as I navigated my first open source contribution in the hopes that others who face similar challenges are encouraged to overcome them. Throughout this post I’ll also explain more about how this helped me learn Rust.

Motivation

The main impetus for deciding to learn Rust was that I had read a lot of great reviews and Rust seemed to be growing in popularity, so I thought it would be a nice addition to my tool-belt. I also use C++ in my day job and saw that Rust was trying to improve on some of the drawbacks of C++ (like easily writing safe, concurrent code), so I wanted to start investigating for myself.

The first thing I did was read The Rust Programming Language (which I highly recommend for anyone else new to Rust!). I breezed through it fairly quickly, dutifully completing all of the exercises. Once I finished, I still felt like I had the training wheels on and I wanted to learn more. I briefly thought about finding another guide or tutorial to go through, but luckily I realized that was a one-way ticket to tutorial purgatory, before getting in too deep. To be clear, the book (and most language introduction texts in my opinion) was great for understanding the basics and acting as a reference as I got more experience with the language. It’s just that I wanted to get to the next level of understanding and be able to write new code from scratch (take off the training wheels). In order to do that, I needed a project to sink my teeth into and push myself towards that deeper level of understanding.

In general at this point I could have done one of two things: start my own project or help with someone else’s project. I spent a decent amount of time trying to think of an exciting project, but I didn’t have any great ideas off the top of my head. Plus I had already accumulated plenty of small, unfinished toy projects on Github, so I started investigating the open source route. That way I would get clear instructions on what needed to get done and I could simply focus on improving my Rust abilities.

This wasn’t the first time I’ve thought about contributing to open source. I’ve had a desire to start contributing to open source software ever since college, but I never felt like I was good enough to help out. It was a clear case of imposter syndrome. I imagine there are many other developers who have run into this feeling. Certainly it’s much more common in an interview but the idea here is the same. There’s no fool proof way of shaking off imposter syndrome, but the fact that I didn’t personally know any of the project maintainers helped me at least decide to give it a shot!

Once I stopped focusing on all the things that could go wrong for a second, I started to realize how beneficial contributing to an open source project could be in my quest to learn Rust. There are multiple experienced developers reviewing your code who know way more about the language and tools you are using so they can quickly explain important concepts you might not understand or even know about. You get the chance to have discussions with people all over the world who have their own ideas for a solution. I think anywhere you can find a cross-pollination of ideas like this is a great place to learn. The trick is to not be afraid to admit you don’t know something, or that your idea is wrong. By no means is it easy to do this, but once you do it is quite liberating!

Clippy

The next step was to find a project to contribute to. After googling a couple variations of “rust open source projects for beginners”, I found Clippy. The best summary comes from their Github: “A collection of lints to catch common mistakes and improve your Rust code”. I am always a fan of developer productivity and encouraging good coding standards, so this project seemed perfect! Part of the reason I picked this project is because the maintainers do a great job of labeling issues that are easier with ‘good first issue’ so that I could quickly find potential issues to solve. I recommend finding a project like this as it makes the initial experience with open source much smoother. Being able to choose from multiple issues that were better suited for beginners reduced the overwhelming feeling of being new. I still had to do plenty of work to acclimate myself with the new code base and the issue I was trying to solve, but I was able to proceed knowing that I was not out of my league.

I ended up volunteering to add a new lint for the use of .nth(0) on any iterator. I’ll post a link to the issue at the end of this post, but the basic idea is that Rust developers should call .next() on the iterator instead of .nth(0) (if you’re curious, check out the docs for nth and next to see why this is desired). It was my job to make Clippy output a helpful suggestion anytime this situation is found. I forked and cloned the repository, and then spent some time building the code and running the tests. I think this is important to do, especially in a new language, so that you can get familiar with the build system first and focus on implementing your solution after. Another reason Clippy was a nice place to start was there are hundreds of lints and therefore hundreds of other examples of what I had to do. I searched for examples of similar lints to the one I was implementing so I could start to understand which parts of the code I needed to change. After a while I was able to cobble together some changes, but I was pretty confident they were not correct. I was stuck and didn’t really know what to do. I returned to the Clippy Github page to see if I could find any useful information and found this in CONTRIBUTING.md:

First: if you’re unsure or afraid of anything, just ask or submit the issue or pull request anyway. You won’t be yelled at for giving it your best effort. The worst that can happen is that you’ll be politely asked to change something. We appreciate any sort of contributions, and don’t want a wall of rules to get in the way of that.

They know this is going to happen, and they welcome the pull requests anyway. Clearly my best course of action was to push it up, admit I’m stuck, and ask for help. It felt weird pushing up code I know did not work, but the reason I chose to do this in the first place was to learn so I pushed up the branch and asked for a review.

Feedback

As I suspected, there were more than a few problems with my initial implementation, but that’s okay! I received encouraging and helpful feedback from multiple users. I learned new macros in Rust like if_chain, and was guided towards more helpful examples in the code related to what I needed to do. After a bit more back and forth, my pull request was merged! It was a great feeling knowing that I contributed at least in a small way to software that is used by thousands of developers every day!

I think it’s important to make a special note about the initial round of feedback I received. It wasn’t condescending or mean, even though I missed some things that by now have become second nature to the maintainers. I received simple, encouraging, and timely feedback that allowed me to quickly make changes and not feel bad about getting it wrong the first time. If the feedback is too complex, disrespectful, or takes forever there’s a good chance I wouldn’t want to contribute to the project again. What’s worse, I may write off contributing to open source altogether! Creating a welcoming environment for new contributors is key to establishing a thriving open source project.

Takeaways

So, what did I learn about Rust after this whole experience? Well, there’s still so much to learn but after reading The Rust Programming Language I was particularly intrigued by Rust’s idea of ownership. I was immediately able to make a connection to my professional work in C++, particularly with regards to move semantics and rvalue references. Rust makes it very explicit who can read and modify data, and the compiler will yell at you if you break the rules. These rules help prevent multiple threads from modifying the same piece of data at the same time, also known as a data race. C++’s rules around data ownership and mutability are less strict, so the compiler cannot protect you from data races as much as it can in Rust. Just by writing Rust code for Clippy and being exposed to the rules that the Rust compiler enforces made me a better C++ programmer in this aspect. Now I am explicitly thinking about ownership and mutability when I write C++ code even though there are no rules forcing me to do so.

Other concepts I found interesting were pattern matching and recoverable errors, which I had no experience with before. Contributing to Clippy gave me valuable experience dealing with these ideas and helped solidify my understanding. These features of the language, among others, were my first significant exposure to functional programming language concepts. Having come from an almost exclusively procedural background, it was interesting to see the two worlds collide. I was excited to have discovered something new, and I look forward to learning more about functional programming languages in the future as well!

Conclusion

To wrap things up I want to reiterate some key lessons I learned from contributing to an open source project for the first time. I think it’s really important to find the right project and have a positive mindset when trying to jump into the open source world. Specifically:

  • Find a project that has a label for beginners, such as ‘good first issue’. These labels reduce the burden of finding an issue to choose, which can be overwhelming on large projects.
  • Take a look at some of the recent pull requests people have submitted to figure out if the maintainers are welcoming. This is a great way to get a sense of the feedback you’ll get should you choose to help.
  • Don’t be afraid to be wrong! No one expects your pull request to be perfect on the first try. Good maintainers expect incomplete and incorrect pull requests, and they chose to be a maintainer for an open source project for a reason. They want to help contributors and love to see new people who want to help!

Hopefully you’ve learned something from my experience learning Rust, or at the very least are encouraged to start contributing to open source software as a means to improve your abilities. I had such a great first experience I decided to volunteer for another issue right after my original pull request was merged! You can check them both out here and here.