Episode #5

How to Learn to Code I: Use SRS and Anki

I believe spaced repetition systems (SRS) are the fastest way to learn how to code, and today I share what I learned over 9 years of experience drilling 5550 cards of technical material into my head using Anki.

November 22, 2020

Show Notes

No notes available for this episode.

Screencast.txt

Transcribed by Rugo Obi

I believe that using a Spaced Repetition System, or SRS for short, is the fastest way to move someone from beginner to solid intermediate programmer. Nor am I alone in that opinion.

Plenty of big names online including Derek Sivers, Gwern and Michael Nielsen have also echoed similar sentiments.

I would call SRS the greatest man-made non-pharmaceutical cognitive enhancer since the computer, but that would be wrong because SRS has been around for longer than computers.

Therefore I'm going to say that SRS is the greatest cognitive enhancer since the printing press.

Today, I'll share my near decade of experience in using SRS to learn to code, and especially I'll focus on six rules for doing it well.

I am a super forgetter. I don't remember the plots of movies I've seen two years ago. Often I don't even remember having seen the movie, never mind the plot.

And sometimes, and I really hate this about myself, sometimes I don't remember having met a person before. When I see them, I just blank.

They're like, 'Good to see your Jack', and I'm just like, 'Oh yeah, good to see you too', not having a clue who it is.

That's how bad my memory is.

Being a super forgetter meant it was very difficult for me to learn foreign languages. Therefore, these were my weakest subjects in school.

Anyway, after I finished university, I met a girl who was using flashcards to learn Spanish, and she recommended I give the technique a try.

I did, and after three months of drilling Spanish vocabulary with flashcards, I had better progress than three years of studying French in earnest at school. I was hooked.

But there was something I needed to learn with far greater urgency at that time. And that was to learn how to code.

You see, I'd just finished a law degree at college and spent some time working in a law firm as an intern.

And I realized that I really didn't want to spend the rest of my life working in that industry, so instead, I’ll become a programmer.

The issue was that I needed to become skilled now, as opposed to in 10 years time.

So I had this thought that if you squint a bit, code kind of looks like a language.

And so I thought, why not dump all the code that I'm learning into this flashcard system I'm using which was called Anki and see if that helps me learn it faster.

So, how did it go?

I started Anki-ing at the start of 2010, about six months later I was earning significant pocket money from a HTML/CSS MVP product.

Within about 18 months I was getting good consulting gigs including being flown over to San Francisco to work for market rates usually reserved for people with five plus years experience.

And within about 30 months, I was able to transform my aforementioned website into a proper Ruby on Rails web app, and earn enough income from that to quit other paid work, and join the ranks of the indie hackers.

I don't believe that any of this would have been possible if it weren't for Anki. So I'm extremely grateful to live in a time where tools like these exist.

Let's begin with some theory behind Spaced Repetition systems.

The overall goal, to use the language of our times, is to flatten the forgetting curve.

--

We're looking at a graph from Wired magazine's interview of Piotr Wozniak, the man who has probably done the most thinking on Spaced Repetition Systems in our generation.

And what you see here is if you learn a fact on day one, it could be a word, it could be a programming concept, then after 10 days you have a roughly 50% chance of having forgotten that fact.

And then, after something like 40 days, you have a 10% chance of remembering it.

However, if you remind yourself of that fact a couple of days later, then 11 days later, then again 30 days later and so on with expanding intervals, then you will remember it for a far, far, far longer amount of time.

Therefore, for any knowledge that's really important for you to lodge into long-term memory, this is the way to go about it.

SRS is already being used in a variety of other fields, for example, many language learning platforms like Duolingo use some sort of SRS.

It's become a really big deal in med schools. I've recently read that something like 40% of American medical school students use SRS systems like Anki, and I've also started noticing it cropping up within tools to learn how to code, such as Execute Program.

While there are many programs that implement the SRS algorithm, the best general purpose one today is probably Anki. It’s a rock-solid piece of code.

I've been using it for 10 years, and it syncs to the cloud and it never loses data. So credit to its programmer Damien Elms.

It's free on most platforms. I think they might charge an iPhone but I'm not even sure of that anymore. And overall, I can only recommend it.

--

Let's take a look at Anki in action.

So, I've opened up the Mac version, and we're reviewing my computer science deck.

There's a question here: What is a functor?

So, what happens now is in my head I answer that. I think a functor is anything that can be mapped over.

So, having guessed at what the answer is, I reveal the answer within Anki. And sure enough, the answer is the same thing. Any type that can be mapped over, and then there's some additional information here, bits and pieces I've copied and pasted off the internet for my private use.

Now, here's the key bit, after I've answered the question, I now have to give feedback to Anki to let it know how well I was able to remember it.

And you can see three options at the bottom of the screen. Either I didn't know it, in which case it'd be reviewed again in a minute. Or, yeah, it was fine - not too easy - and I'll review it again in a day. And it was easy - in which case I won't see this again for four days. That was easy for me so I'm not going to see it again for four days.

And now the next question comes up. What is a higher order component? And then I can reveal the answer and check whether or not I understood it, then give the feedback to Anki about how I did.

And in this way, Anki is able to build up a sort of model of what my memory looks like, and then optimize what cards they show to me, in order to reduce the amount of forgetting I do.

--

I noticed three advantages to using Anki regularly, the first and biggest by far is chunking.

Chunking roughly is the idea that when you gain familiarity with any sort of technical topic, you no longer have to deduce everything from first principles. Your mind can rely on pre-cached knowledge, and then applies deductive powers at this higher level to these chunks.

For a common example, think about how chess players don't just see individual pieces but they see structures, they see multiple pieces together in certain positions. Or how musicians don't just hear the music, they hear chordal progressions and so on.

So, what? Why should you care about chunking?

Well, your performance in any field (like programming) depends on your intelligence which is fixed at birth, as far as we know, and your pre-existing knowledge.

Considering you can’t change your intelligence, you might as well work on improving your pre-existing knowledge and focusing on creating possibilities for chunking is the best way to improve your performance and is functionally equivalent to having a higher IQ. Proviso: a higher IQ in that specific field.

Being a good programmer doesn't stem from being able to bash out code at RSI-inducing speeds; rather it stems from being able to scan the space of all possible program designs, and then pinpoint which design is going to take only 10 lines of code and cause you zero headaches, versus perhaps the more obvious design that will cost you 1000 lines of code and cause you at least as many headaches.

The second advantage of Anki is fluency.

After my first couple of months of regular practice, I started to get this feeling that, woah, I know exactly what to type, and it was as if I was suddenly able to play guitar by ear or speak French in conversation without having to think about it.

The third advantage of Anki-ing is that it promotes consistency in your efforts to learn code.

Due to how Anki is designed, it creates this sort of back pressure to get your reviews done.

If you miss a day, there are more reviews later. And I find this is very motivating to get you to do something every single day, which I think is critical when you're starting out learning how to code.

--

Over my nearly 10 years of using Anki, I came up with a set of rules that helped me to use it more effectively. In particular, not to drown myself in the workload.

You can see those rules here and they have an acronym along the side here in green -CODERS- and I want to assure you that I definitely didn't spend a really long freaking time trying to come up with that. It was totally off the cuff.

*First point: *Continually add flashcards from things you find hard, or that leave you with scars.

So, this is about inculcating a collector's attitude that whenever something is challenging, you're going to harvest that and turn it into some sort of flashcard, something that you can learn from.

Let me show you a couple of examples.

I created this particular card about Git, when I was unable to tell the difference between HEAD@{1} and HEAD~1.

They both had HEAD and 1 in them but I didn't really get how they differed from one another. So I looked it up and created a card.

The next card here is something that came from a close call. I had a security hole in my web application because I failed to understand the implications of something.

Basically if you put a login token in an email and the link isn't HTTPS, then a packet sniffer in the middle can grab that token and impersonate the user.

Point two: Opting for learnings with long term earnings.

So there's a cost to putting a piece of knowledge into Anki, therefore you should be picky about what you put into it.

You want to choose items of knowledge that are going to pay interest for the rest of your life, as opposed to some piece of knowledge that's going to have zero worth to you in five years time.

For example, a JavaScript framework that gets cast aside like a used mattress as soon as the next one comes along.

So, how do you know what kind of knowledge is going to prove valuable to you over the long term?

There's no definitive way to know, but I would suggest a few things.

One is to focus on fundamentals, to focus on ideas that are common across various programming languages, and also to take into account the Lindy effect.

This is the idea that the best predictor of how much longer some technology will last, is how long it is already lasted.

This implies an approach to learning that focuses on topics that are pretty unsexy, things that are stable and have been around for a while.

I've made a more specific list here with some things that I think you shouldn't anki-ify versus some things you should anki-ify.

Let's go through some specific examples I've come up with here.

So, don't anki-ify the API for some web framework, for example React or Rails, especially for some particular version of that framework versus do anki-ify the abstract API for some data structure that's available across most languages, for example, array map, array zip, array reduce, etc.

Don't anki-ify proprietary technology like Firebase or something in AWS, do anki-ify protocols and standards like SQL, HTTP, JSON, the purpose of whatever components you're using, as opposed to the particular implementation of it.

Don't anki-ify exact function signatures, syntax, argument order, but do anki-ify computer science concepts like regexes, encoding, how binary works, how system calls work, how threading works, how unit testing can be done, etc.

Don't anki-ify niche languages. Like I invested in this one called CoffeeScript that went nowhere. Better to anki-ify things like Unix tools, bashscript, C, Vim, whatever language is winning the most user share in the world. Today I guess that's JavaScript, maybe Python.

Don't anki-ify unproven new features to existing languages. Like there was a bunch of HTML5 elements that were never really used, and I dumped them all into Anki and I regretted that.

But do anki-ify the popular, heavily used features. Like, it's a good idea to have a list element in your HTML Anki if you're just starting with HTML, because they are everywhere.

Point three: Drawing on problems you face through some real world use-case.

Like sex, programming is better and more enjoyably mastered through practice than through reading about it.

So the point of this rule is to protect you from too much bookishness, to protect you from accumulating countless cards, just in case you might one day need them.

What you should do instead is focus your programming efforts on actually doing things.

And only when you encounter something you don't understand, or you're face-to-face with a part of the stack that confuses you, then you can think about creating some cards.

Point four: Executing all code before adding to your Anki load.

This serves a couple of purposes.

One is that it protects you from drilling crap.

There's plenty of code snippets online that are just wrong or hopelessly out of date, and you don't want to waste your time adding them to your Anki deck and drilling them and generating a false sense of confidence in that knowledge.

If you have to actually execute the code, you will become aware of the mistakes that lie within straightaway and you will fix them before adding them to your deck.

Secondly, this ensures that you understand what you're adding to your Anki decks.

It's far easier to remember something if you understand it, and although you could get by in some schools just by remembering the secret password to whatever was on the test, that is not good enough for real world programming, you have to actually know what's going on.

Point five: Referencing sources, as you would in academic courses.

The idea here is to just write down where you found some particular piece of knowledge originally, what blog posts, what book, doesn't have to be too much detail, so that you can go back and revisit it in the future if you need to.

In this particular card, I've taken a snippet from someone's answer Pavel on Stack Overflow, and used that for my answer.

But then, I've also left a link to the original source, so if I no longer understand this particular paragraph, I can go back to the original Stack Overflow thread and fill in the gaps.

Relatedly, I would advise you to tag all your cards. You can see here that I have Postgres and then Ruby and then Vim and so on.

The reason why you should tag is because it allows you to organize your cards better and do spot drills, or remove sections that later become useless because you made some sort of mistake in judging what would be worthwhile in future.

Point six: Solidifying and regularly tidying the elision and qualifying.

So, part of the idea here is to keep your deck tidy. Modify or delete cards that later prove incomplete or out of date, or just simply impossible to remember - that's also a problem too.

For example, I noticed that I was unable to remember this particular card, and the reason was because essentially it required me to know four different things, each of these flags. Therefore I ended up breaking this card out into separate cards.

By the way, if you're looking for some general advice on how to write good cards, there's this great article, Twenty rules of formulating knowledge that you can Google, and I recommend you do.

This sixth rule also prescribes that you should spend time solidifying your understanding or modifying cards and creating connections between them as your knowledge improves.

For example, in my first few months of ankying, I had a very primitive understanding of Git and I made this card -in git conflicts the part after the === is typically whose side- and I just put it in their side because I didn't really understand the concept of branches.

However, later on when I did understand it, I updated the card to say, the side of the branch, you just merged, and then in the future I made that more accurate again.

Often this implies that you can delete cards, because your increasingly fundamental understanding means you don't need as many specifics.

Over the years, I ended up using it to learn all sorts of things like music theory, how to write better in my mother tongue, and also general life lessons. Things that I felt were very important and I needed to be reminded about from time to time.

Here's a couple of examples.

--

People will tell you that there are no shortcuts to learning how to program, they're wrong.

And they're also kind of right.

Anki will get you there faster, but you will pay for that speed. You will pay for it in terms of mental exertion. You will pay for it with your discipline. And you will pay for it with drudgery.

Anki is a shortcut, only in the sense that you might be able to get to a destination sooner by going right over the mountain, rather than walking around at sea level and not exerting yourself at all.

I'm advocating for Anki today, not only because I want you, the viewer, to be able to reap the private rewards of being able to code sooner, but also because I'm excited.

I'm excited about all the wonderful things that the next generation of programmers will be able to build, wonderful things that will enrich our lives, wonderful things that will benefit our society. And I want us to get there faster.

To close up, I would encourage you to test the waters for yourself, try Anki out for 30 days.

You can hashtag #30daysofAnki on Twitter to talk to other people doing the same thing and see how far it takes you.

If my experience was anything to go by, you might want to strap in.

Thanks for watching.