Learn X Language Fast
One thing they don’t teach you about programming is that when learning a language, you’re not going to spend nearly as much time learning the syntax of the language as you will learning the libraries of that language.
Introduction
Programming is just as much about having the right conceptual constructs as it is about being able to express those concepts in the language. This is unfortunate, as for most of us, the elegance of an algorithm stated in pseudo code holds a crispness that the impure, and messy implementation obscures. Even if you’re a genius for algorithms, you’re going to have to learn a language, it’s popular libraries and a whole lot of other particular knowledge bits, like it or not. The good news is that there are techniques to speed up this process of learning so that you can spend more time on the fun parts of programming. In this post, I’ll share a few of the strategies I learned to improve my learning speed. I hope these tips can help others to improve their learning speed as well.
Define the Nuts and Bolts
My goal throughout this learning process has been to build a web application for smarter note taking. The specific technologies, the nuts and bolts, which I had to learn were determined by the end goal. That is, I don’t consider the HTML element sizing APIs to be particularly interesting beyond the fact that knowing them helps me achieve my goal. The faster I can learn, the faster I achieve my goal (or at least can focus on the core problem surrounding it).
Here’s a few of what I’d deem the nuts and bolts of this process
- HTML Element types, and Element API functions such as
getClientX
, and so on - CSS positioning rules such as the numerous “flex” layout options
- Javascript core library functions
setTimeout
,Math.*
, etc - React framework functions such as “hooks”, and component class functions
- browser event handlers types and names
- and more..
What I’ve listed is the substrate upon which I can build an application which brings some unique value into the world. I’d consider the application as the “pure” idea which I described in the introduction. Since my application needs text input, interesting styling, responsive html elements, and to interact with web APIs, I need to know all these technologies, but that laundry list of nuts and bolts does not alone create the app. Learn the nuts and bolts faster and you get your app faster.
Techniques
Now that we understand the kinds of things which make good candidates for rapid learning, I’ll go through the methods I found most effective.
Anki Cards
Anki is an open-source program that implements a learning technique known as spaced repetition. Simply put, spaced repetition is a flash card program that increases the interval of time between repeating a particular card depending on how well you can recall the information on the card. The program is designed to more frequently show cards which you are less familiar with and less frequently show cards you’re confident in. There’s many programs which implement spaced repetition but I chose Anki since it’s free and has a community following.
The insight that unlocked really unlocked the effectiveness of Anki for me, was realizing that Anki could be used for learning to program. I had previously used Anki to study a foreign language, but it using it for programming had never occurred to me. I happened to see a John Carmack tweet about how he had discarded an Anki card for an obscure command line utility when it clicked in my mind that there was a whole domain I could be using with Anki.
A few examples of cards I created in Anki for Javascript might help make the concept click for you. Since my biggest hurdle in programming Javascript was knowing the ins-and-outs of positioning in CSS and Javascript, most of my cards are meant to make this knowledge second nature to me. Here’s a few examples from the deck.
-
clientWidth / clientHeight: the width / height of a block element’s content. Does not include borders and padding.
-
offsetTop / offsetLeft / offsetRight / offsetBottom: The integer pixel distance to the nearest offsetparent.
-
justifyContent: A css property affecting block elements in the flex layout. Describes how elements are aligned and spaced along the main access. Options include space-around, space-between, space-evenly, flex-start, flex-end, …
As you can see, this is fairly mundane stuff. It’s the kind of thing that, if I don’t take a few minutes to add and review in my Anki deck, I will forever be banished to having to Google for phrases like “size of element content” or “offsetTop definition”. In fact, having to Google something more than once has become my cue to add that concept to the Anki deck, should it make sense.
If this technique seems silly since it only takes a few seconds to Google something, I’ll agree with but with a caveat. Googling for a simple concept breaks mental flow and introduces more distractions to the process. Inevitably, it will cause me to spend more time on the boring stuff instead of the concept I’m trying to implement.
Fast Prototyping
In programming, it’s important to be able to quickly test an idea. When I started learning Javascript, I was editing files on my local file system and serving them using a Python development server. This worked, but it was slow. It meant copying files whenever I wanted a new scratchpad, and having to refresh the page every time I made a change. Even now, I use VS Code which is a fantastic light-weight IDE, but I still find that there’s faster ways to test small ideas.
More recently, I learned about two tools meant to make the process of prototyping fast, and enjoyable. The two editors I’ll use when testing out ideas are StackBlitz and repl.it
-
Repl.it is my go to tool for learning the Javascript language itself since it supports an in-browser node environment. For example, when I started learning the language, there was a lot of syntactic sugar such as object destructuring that I had to learn the particularities of. Repl.it is still my go to place for learning language fundamentals.
-
StackBlitz is an online version of VSCode designed for building web applications in the browser. You can write vanilla html/css/javascript with it, but importantly for me, it has great support for React with NPM package management, meaning that if I wanted to try a new NPM library, the first thing I’ll do is make a new StackBlitz project and have it up and running in just a few seconds.
So there’s the tooling for you, but what do I mean about prototyping? What’s something that demands a prototype? Here’s a couple examples
-
Beginner Focusable Textarea. When I started learning react, I would make simple components such as this paragraph element that turns into a textarea when clicked.
-
Intermediate Drag and drop. I wanted to learn the library ReactDragAndDrop before using it in a larger project so I made a component which allows you to reorder paragraphs using drag and drop.
-
Advanced Textarea Caret Position. I was making an app that required smoothly transitioning the caret between two stacked textareas. Moving the caret seamlessly required measuring the pixel offset of the caret in one textarea and then finding the corresponding character in the adjacent block. This is where learning HTML element sizing became important.
Pretty much any time I have a question about how something works in Javascript or React, I’ll boot up a repl.it or StackBlitz and try to solve it. The speed of getting started adds to my wanting to continue to learn. Remove friction from your learning process wherever possible.
Read Code, Inspect Websites
I like to think that I’m so smart and creative that I’d be able to come up with an implementation of basic framework components just by working on a few small beginner problems and thinking about how to generalize them. That, if I just write two or three websites in vanilla javascript, I’ll have an epiphany and the foundations for writing the React framework will simply roll off my finger tips the next time I start writing. Sadly, I’m not savant, and most, if not all, of my programming ideas originated in someone else’s head. Pitiful as that reality might be, if I were to accept my fate, then the next question I should ask is “and how do I take advantage of that?”.
The answer is to read other people’s code.
One of the secret skills of faster learners is finding the right libraries to read and learn from. Want to know how I wrote some of those examples in the Stackblitz projects I linked in the last section? Easy, I read and then replicated the core ideas of an auto-resize library, and a drag and drop example. When I started writing full-sized applications, I leaned heavily on the examples that I could extract from this exemplary React “realworld” app. I can’t teach curiosity, but I will say if you’re naturally asking yourself “and how does that work?”, then you’ll be on the right path here. If you’re new to coding in general, know that you can search for just about any coding concept and append the word “github” to your search. You’ll get an abundance of examples to dive into.
One extra tip about reading code: if you find Github project that you like or think might be useful in the future, star it. That makes it marginally easier to find later and allays the feeling that you might lose something valuable.
Besides reading open source code, I’d also recommending reading other website’s APIs. Web APIs are generally JSON messages and if you’re writing a javascript application, it’s very likely that you’ll end up needing to write some backend code. Therefore, reading the JSON messages your favorite websites are sending can give you a good education on how you might want to design your backend. I’ve personally learned quite a bit by inspecting and comparing website API styles. For instance, the apps Roam and Notion are both quite popular in the productivity space right now. Roam is implemented using a websocket API that sends compact diffs over the socket whereas Notion uses a POST request that sends over the entire block of modified text. Not only can I learn how I might want to structure my JSON APIs, but the contrast makes me consider the message-size versus developer-legibility tradeoff. Additionally, it showed me an area besides git where diffs are useful. That’s the wonderful thing I’ve discovered about learning web in general: you don’t have to take courses on how to do this stuff, you just need to know how to look.
Don’t get stuck, debug
You won’t be able to learn quickly if you are constantly getting snagged on insurmountable errors. I found that, because the browser’s console is capable of logging objects (as opposed to only string representations of objects) that the console is an extremely powerful debugger and calling console.log
became my debugger of choice. But the console is just one component in a suite of powerful browser developer tooling which will make your web learning experience faster. So, if you don’t know the very basics of using the inspector (right click -> inspect) then this will blow your mind. If you already know this, skip the following enumeration.
-
The log and console tab. This not only displays logs but also functions as an interpreter. It’s great for testing small snippets of javascript. One trick I especially like is that if you log an object and right click it in the log, Chrome gives you the option to save the object as a global variable, allowing you to manipulate it in the console. Very helpful!
-
The network sniffer. I use this not only for my own code, but when I’m interested in seeing how other websites are designed- what their payloads look like? What headers do they use? What does the auth flow look like? What background requests are they making? Does the site use websockets? The network inspector is an amazing tool.
-
The
application
tab. If I need to understand what’s inlocalStorage
or what cookies the app is storing, this tab allows introspection and let’s you clear these variables if you need to logout from your site, or delete corrupted state. -
The
elements
tab is helpful for viewing the structure of your site. But you probably already know this. -
The
performance
tab is useful when you write larger applications and start diving into performance. It’s not a bad exercise to try it out: hit record and then hit some buttons in your application. Then stop the recorder and try to interpret the flamegraph. What’s taking longer to compute in your application- rendering or scripting?
There’s many ways to debug, and as a novice in the language, you will probably be leaning mostly on console.log
. Knowing the advanced tools exist will be sufficient for now since advanced tools are not that hard to learn and can be picked up on-demand. Knowing they exist is more important than knowing how they work for this stage.
Before ending this section, I think it’s worth mentioning some of the tools I tried and then abandoned to show that I didn’t come to these conclusions overnight.
-
VSCode’s debugger for Chrome. An IDE-style debugger which launches a Chrome instance in debug mode and allows for stepping through the code and setting breakpoints. I found it to be more trouble than it worth since it was cumbersome to set up and marginally better than print statements.
-
Other IDEs. I come from the world of Java and recommend Jetbrains Intellij to anyone working on Java code. However, though there’s no doubt that Jetbrains Webstorm is a great product, there’s no free version, so I abandoned it after the 30 days trial ran out. Too bad, because the intelligent code-recommendations are something I miss.
-
Chrome’s built-in debugger. One facet of the browser’s amazing developer toolset that I don’t make much use of is the debugger. It’s accessible under a tab called
sources
which displays the source code for the webpage. It allows you to set breakpoints similar to an IDE. I found that this works fine with simple javascript applications and I won’t discard it, I just found print statements more faster, lower friction, and more effective.
Digital Books
When I was starting to learn Javascript and the whole area of front end web, I found Marijn Haverbeke’s book Eloquent Javascript to be good learning assistant. It features inline coding exercises appropriate for someone with coding experience but little to no front end experience. Furthermore, Marjin’s in- depth blog posts just happened to be a treasure chest of topical information for the projects I was specifically working on.
Yes, this section is pretty short. That’s because I like to learn by doing then reading, rather than by reading then doing. By this I mean that I’ll have an idea for a project and discover what it is that I need to know along the way. For example when I just started out, I decided I wanted to make an app that used the Github users’s API to display and search users. This required that I learn at the very least
- fetch API
- Promises API
- callback based programming
- element creation
- element positioning
I discovered Marjin’s book partway through this process and used it to learn some of the fundamentals of front end web- but I won’t have had the motivation to read it until I had a goal for why I was investing time and effort into reading it. For me, technical books are something I read on-demand, which is different from how I read literary works.
Those are the techniques that I learned while learning front end web. I will reiterate: continually Googling for every hang up you run into works, but I felt that these methods decreased the Googling rate over time compared to my previous method of not doing anything special after finding my answers.
Conclusion
You’re never going to get away from having to learn a lot of highly specialized information about libraries and platforms when you’re learning a new language. Speeding up the process of learning the nuts and bolts will make you a more effective programmer and acheive your implementation goal faster. I hope that by sharing my experience, it will improve yours.