I used to work at a language-agnostic software consultancy. As an engineer there, I could be allocated to any project, on any stack, in any programming language, where I would be expected to TDD and pair program with enough competency to justify our $240/hour rate. Ideally, we got a couple of weeks’ notice that we would need to pick up a new stack. In practice, sometimes we found out day-of (to be fair this only happened to me once).
When you find out day-of, the trick is to have mastered your IDE so you can navigate around the codebase with enough ease and confidence to make it look like you know what you’re doing for a few weeks until you get up to speed on the language.
Some people hit the skate park, or do donuts on 4-wheelers
I do this pic.twitter.com/xISuu9AtiF
— Chelsea Troy (@HeyChelseaTroy) July 1, 2020
But this diversion only works for a week or two, so we’re still presented with a very short timeline to get from no knowledge, to consultant-level knowledge, of a programming language. Yikes.
I have a few tricks that I use to make this happen.
Here’s what I don’t do: I don’t focus on memorizing the details of the syntax.
First of all, I know that I’m going to pick up the syntax from reading example code to learn the answers to the questions I do ask (keep reading to find out what those are).
Second of all, since I haven’t written this language before, I don’t know yet which syntax I’ll be using most often, so I’d be at a high risk of spending a disproportionate amount of time learning structures that I’m not going to use. For example, I use generics a lot in Java, in part because I find myself using Java in large/complex systems or extremely generalized libraries. I don’t find myself using generics much in Swift because I typically use Swift for iOS client apps where each piece of code has a very specific use case. So, when I teach Swift, I don’t go over generics. I’d have to contrive an artificial situation to make them relevant.
Third of all, syntax is one of those things that I can look up on-demand with a search engine. When I need a case statement, I can Google “[LANGUAGE] case statement” and in most cases, the first result will tell me what I need to know.
Fourth of all, syntax is a hard thing to accidentally mess up without realizing it. If the syntax is wrong, my program won’t run. Compare that to if I make an inaccurate assumption about precedence in the language. I think I’m assigning the result of an operation to a variable, but I’m really only assigning part of that operation, then finishing the operation on the assigned variable and throwing away the result. Now, when I reference the variable later, it’s null. I can’t figure out why because I am looking at the line where I am under the impression that I assigned the variable. Syntax doesn’t hang me up on insidious problems like this.
So instead of drilling syntax, here’s what I do:
1. When I’m learning a programming language, I ask a set of questions that get to the crux of what I need to know.
The set of questions focuses less on syntax (which is relatively google-able) and more on aspects of the language’s organization and implementation.
2. I cement new information in memory by establishing a relationship between that information and stuff I already know.
I go through the programming language questions, comparing the new language to a programming language I’m more familiar with.
I have a talk where I do this as well, typically introducing folks to Swift by comparing it to whatever programming language the audience knows best (as determined by a survey whose results might look like this):
Here’s an example of the talk itself.
This version ran 52 minutes in length and used Python as the “anchor language,” with Swift as the new language.
P.S. If you want to:
- Book me to learn a language live on screenshare for your company, or
- Sponsor a live coding session where I do this on YouTube
Programming Language Questions:
- Type system: Is this language statically or dynamically typed?
- What are the basic types for representing strings, numbers, and true/false values?
- What types does this language provide for representing collections?
- Conventions: Is this language conventionally snake_cased or camelCased?
- Mutability and Legibility (in other words, referencing & writing to variables):
- How does this language determine which variables are mutable?
- How does this language define the scope of a variable?
- What is the default, and the options, for the privacy level of a variable?
- Paradigm (imperative/functional): Can you write both of these styles with this language? Is it oriented toward one or the other?
- Collaboration: How does this language deal with inheritance, or interfaces?
- Handling null: How does this language deal with null values? What do developers need to do, if anything, to handle null values?
- Precedence: If multiplication and addition are in the same expression, what gets evaluated first? If the “and” (possibly represented with &&) and “or” (possibly represented with ||) operators are in the same expression, what gets evaluated first?
- Associativity: What’s the result of 9 / 3 * 3 in this language? Why? What’s the result if you take a variable, j, assign it to 0, and then run j *= 2 + 1? Why?
- What does the language compile to? It’s worth noting here that the way a language compiles is a characteristic of the compiler, not the language. Different compilers can do different things with the same language front end; for example, standard MRI Ruby compiles to C, and JRuby compiles to Java. What you want to know is, what does the compiler you’re using do, and why?
I go through these questions and write down my findings by hand with a pencil and paper. The process of slowing down and writing helps me cement the information in memory. You are, of course, welcome to do that, or else type up your notes.
I created a worksheet that you can copy and use for this exercise. You should be able to type in your copy on Google Docs, or if you prefer, you can print it out and write on it. It has three columns—one that lists the questions, one for your anchor language, and one for your new language.
I have a system that helps me quickly develop proficiency in a programming language. I don’t start by drilling syntax. Instead, I have a set of questions that I’ve developed over time learning programming languages, and I answer each of those questions for the new language. In addition, I anchor my new knowledge in my existing knowledge by comparing the new language to a language I already know on each of those questions.
I sometimes give talks where I demonstrate this (see video above), and would do one for you, under some conditions 😊. I also have provided you with a worksheet to help you go through the process yourself.
If you liked this piece, you might also like:
The debugging posts (a toolkit to help you respond to problems in software)
The Listening Series (Prepare to question much of what you know about how to be good at your job.)
Skills for working on distributed teams (including communication skills that will make your job easier)