How to learn in spare-time?

Just a question to put out there, perhaps especially for Rustaceans who don't code Rust most days (due to work, family, whatever!)

Any advice for getting more bang for the buck and retaining knowledge between weekends and sporadic nighttime hacking?

Case in point - I tend to learn best by doing and so I figured if I pick a starter project I inherently want to do, I'll be motivated to push forward... that's worked for me in the past when learning new stuff. So, the kind of things I want to build for fun is like gamedevy web experiences (I used to make things in Unity and Flash, back in the day, and would like to see webassembly bring fun games back to the web) - but there's so much to learn in addition to the usual Rust difficulties (web_sys, js_sys, webgl, etc.) - and I feel like I'm spinning my wheels a lot in ways that aren't paying off the way I want.

Of course there's not going to be a one-size-fits-all answer here, but it'd be great to see some stories of inspiration from those who climbed the mountain, even if not in spare time... like what worked for you to really make things click ... where you learned to anticipate the borrow checker instead of fighting it?

This is exactly how I learned, so hopefully the following will also be useful to you. What I found most valuable:

  • following along the problems and other answers here, and trying to come up with my own answers (as well as asking a few questions of my own).
  • Likewise, following and helping / participating in discussions in chat, in particular #beginners and #code-review on the community discord server.
  • doing some programming exercise-type questions, such as rustlings or advent-of-code. I probably should have done more of these sooner, but .. didn't.
  • absolutely, just having a small concrete problem to solve and work on to learn by doing, but it can be tricky to make up good small problems for yourself.

For me, with respect to retaining knowledge, the key advantage of the discussion-based points was that explaining things to others, and coming back to the conversation a day or two later as others had added more insight, really helped carry things beyond one evening's hacking session quickly forgotten.

3 Likes

I'm still learning (see: posting history), but what I do know has been learned outside of working hours.

I started by doing Advent of Code and reading the Book. There is also Exercism and leetcode. Many options for starter problems.

To go deep, you need to solve hard problems using Rust. The zeroeth step of mastering any technology is to understand the problem. The last step is understanding the solution. So working on problems of interest to you is the best way, because you understand those problems. Start with simpler solutions - use Box and to_owned and Rc liberally. Some of these borrowing problems aren't really important. Consider that every object in Java is boxed. A Box here or there to stop feeling stymied is not going to kill you.

If you bite off a problem that's too much, spit it out and take a smaller bite. Then go back and refine your solutions in light of your burgeoning understanding. I suggest rereading chapters of the Book, and also chapters of the purple book. I find there's usually more juice to squeeze in the re-read.

1 Like

I don't know if my answer will be useful, because my starting position was probably different. I've learned maybe 20 programming languages so far, put to extensive use at least 5 of them. One of the 5 was C++, one of the 20 was Haskell, which were AFAIK big influences of Rust.

I started by reading the (first edition) of the book, mostly because I was curious about the language. I have some time when travelling that is not suitable for actual coding, but reading and thinking about it is fine. So, then I've read bunch of other shorter Rust books (The nomicon, the too many linked lists). After ingesting the whole thing, I've started to play with it.

I've chosen a project that was in retrospect way above my head ‒ at that time, the tokio-core was just starting and competing with rotor. I didn't get why they were doing things the way they were and wanted something that made sense to me. So I've tried to write my own event loop. I've done that few times in C. I've learned some Rust and why the other two were doing it differently than in C. Eventually, I've thrown that repository away (well, not really deleted, only abandoned). The most important thing this exercise gave me is understanding that rustc tells me not only when my code is unsafe, I have typos, but also that my design is stupid. The difference between good and bad design is visible in the hairiness of API, the amount of „forcing“ everything to align, etc. Since that time, I regularly kill longer branches, commits on weekly basis. I've learned to let myself be led by rustc. If the design is good, everything feels smooth.

The other way I've learned most of what I did is something like drive-by contributions. If I find a bug (or want some API extended) in some crate, I sometimes report an issue, but if I have the time, I just send a pull request. Even when reading documentation, I often click on the [src] button and read through a function or two. This way I come into contact with a lot of someone else's code.

So, in short, I've learned by three things:

  • Challenging myself beyond the current abilities.
  • Throwing a lot of code away.
  • Working with code of others.
4 Likes

This is probably going to seem like obvious advice, but maybe that's the best kind in this case? :joy:

I learned first by following along with Rust By Example. Then I picked a project that I was interested in following a tutorial for writing a software-only 3D renderer in C++. Except I did my implementation in pure Rust, trying to be as idiomatic as I could along the way. In fact, any of these tutorials will be an awesome place to start if you're into computer graphics: https://github.com/ssloy?utf8=✓&tab=repositories&q=tiny

There was also mention of Ray Tracing in One Weekend on the forum recently, which is very similar to the ray tracing course in ssloy's tiny* repos.

1 Like

Is there a doc / tutorial somewhere that outlines simple actionable advice that is typically learned the hard way?

For example, I think the following might be true (not 100% sure):

When designing an API, strongly prefer taking &self as an immutable borrow even if you are mutating the inner contents, as long as the caller doesn't need to mutate the returned values. This does mean interior mutability which typically has the cost of RefCell, but not doing this will create problems later where you want to use the returned values within overlapping lifetimes. See code example of the problem

This is the kind of advice that you can typically find in threads discussing the "Rust learning curve". Some other gotchas are storing borrows in struct fields (especially self-referential structs), and &mut self methods with disjoint field access.

But yes, you will definitely run into these issues a few times before you learn how to avoid them. An interesting side effect is that learning from these experiences will change how you design APIs in other languages, too. This is a pretty common observation, which I find fascinating.

3 Likes

Yes, I found Rust made me think safer and spot dangling references earlier in C++. Quite amazing!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.