Almost everyone claims to have the course or curriculum for learning code, be it giant colleges or small startups. However, I believe programming is one those skills that cannot be truly learned from lecturing or reading. It is a practical skill, much like playing an instrument or delivering a speech, that needs practical action. It is easy to teach the theory (and with programming, that is still a must), but making the transition from idealized textbooks to real-world problems demands real exposure.

A Practical Sport

You have to throw yourself into programming in order to learn programming. This runs counter to most curriculum which, instead, teach the foundation first with the hopes that it will prove useful later. If the actual world was full of LRU caches and linked lists problems, this may be true. However, it’s easy to see this is not the case.

In the real world, you are dealing with unideal situations all the time. The technical stack is uneven with some parts modern and others ancient, one language works well in one domain but another excels in a different area, hardware and time constraints limit fancy implementations; these are all real problems that don’t have a course or a textbook.

To truly thrive in programming (and any sport) requires equal parts rigor and flexibility. You need to learn the basics in great depth so they all become second-nature; yet, you also need to unlearn rigid patterns so you can begin to think more openly.

Much like a dance: you glide through each practiced motion effortlessly all while thinking, on a higher level, what you wish to convey, what you wish to personally express, and what creative routes you can take to do so.

The old rules of learning that apply to practical sports apply to programming as well.

Progression

There is a clear sense of progress with any serious learning. However, everyone ends up with different strengths and weaknesses. Part of this is because of individual characteristics, of course; but, I feel a large majority is due to the approach of learning.

The most common approach is to isolate a concept and teach it in its simplest form. An overwhelming majority of classes and courses are set up this way. Going through this strategy, be it with Mathematics or Writing, you are expected to learn the ABC’s of the domain and some basic usages. Then, you learn more layers, adding more sophistication to that base. Eventually, with enough layers (B.S., M.S., Ph.D.) you are called an expert.

Another approach is what I like to describe as going through the motions. Instead of learning the foundation first, you are exposed to the actual practices that go on in a domain. At first, you won’t be able to recognize the weight of anything you are doing; it will feel like a long-list of seemingly random actions. Yet, you gain tangible experience and concrete memories that can be connected with theory post-hoc.

These two approaches are not antagonistic. They not only can coincide but are often required in varying amounts for every field. Moreover, in even one field, different stages of learning need different amounts of each approach. Math, for example, is very practical in grade school and very theoretical in post-secondary school. But, no amount of theory can substitute the physical experience of counting; and counting remains forever relevant even in doctorate publications.

With programming, there is no precise time where you are free from coding practically or free from theoretical fundamentals. Unlike other domains, programming flips and flops between the two approaches regularly. One moment, you are memorizing the basic syntax of a language by literately typing the code and, in another moment, you are designing an abstract schema for a database. With some concepts, like data structures, you have to simultaneously memorize the code and learn its significance.

Revisiting

One key in learning is to revisit “old” concepts. With many skills, first looks can be deceiving, and a single concept often requires multiple passes at different levels of expertise before they can be fully comprehended. In programming, this is almost always the case.

Take the follow code for example:

let sayHello = function(name = "User") {
	console.log(`Hello, ${name}!`);
	return;
}

sayHello();

It looks like a simple, basic function, one you could find in a JavaScript 101 book. However, any code can be deceptively simple, particularly with higher-order programming. To try and illustrate this:

With the above function, a beginner’s mind would have a thought like so:

If I type these characters and symbols, I can make the computer say hello.

With the exact same code, an amateur might say:

This is a function called “sayHello” that accepts one argument and prints that out before returning.

An experienced programmer:

This is ES6 JavaScript code with an optional parameter, a function bounded to a certain scope, and string interpolation.

An expert:

This is a function, which in JavaScript are first-class objects, being run by a JIT complier like V8.

These are just examples, but notice how all of these are sound but different. It is this nuance and depth that is important to not only notice but master as well, especially with programming.

End Note

There is a lot to cover about learning to code, so this writeup will be expanded routinely.