When I first learned to program, I remember wanting nothing more than to practice and improve. There was only one problem: how the hell do you practice programming?
It turns out some answers lie in the creative arts. In particular, music and painting have offered surprising lessons on how to study software engineering. I hope they’ll help you as much as they’ve helped me.
Focus on Fundamentals
What are we learning?
If you love algorithms, and I mean really, really wake up in the morning and can’t wait to dig your hands into segment trees and recursion — then congratulations. You’re the coding unicorn we all aspire to be. The rest of us humans need to wrestle with the question: why bother with coding puzzles at all? Is it just to pass technical interviews?
When practicing anything, it’s important to know why you’re studying what you’re studying. What specific skill is it targeting? What weak spot are you strengthening?
I would argue that coding challenges don’t just teach a specific lesson (like how to traverse a binary search tree), but also the underlying process of engineering. In other words, they target fundamental skills.
The reason coding puzzle prompts seem so arbitrary is because they are. The most valuable knowledge gleaned from them is not the solution to the problem, but how to solve a problem. It’s an important distinction.
How do you break a large problem into smaller concerns? What details can you abstract to allow higher-level thinking? What edge cases lie waiting in a solution? What are the trade-offs between one data structure versus another?
All the questions above test fundamental skills. These skills are, like the data layer at the base of an application, what all other knowledge and skill depends on. These are not the trills and ornaments of a piano sonata. They’re the fundamental harmonies on which the whole sonata rests.
What Skilled People Know
Hear me out: a skilled artist doesn’t know how to paint a landscape of Central Park in Autumn. Instead, a skilled artist knows how to paint light on form.
A skilled artist doesn’t know how to paint leaves on trees. A skilled artist knows how color behaves.
Learn the fundamentals, and the rest is gravy.
Painting from Life
Copying-and-Pasting vs. the Primary Source
The painters I know, the ones who are really serious about their craft, always paint from life. What does that mean? To paint from life means that the artist is painting the actual thing in front of her eyes, whether that’s a model, the landscape ahead, or a still life.
Not a photograph of a model. Not some other artist’s rendition of a landscape. Not some other person’s painting of a painting. It means painting directly from the source, solving the problem yourself.
To look off someone else’s painting of a sunset instead of standing outdoors yourself means that you’re copying a solution, not inventing one. It’s the equivalent of copying-and-pasting snippets off Stack Overflow.
Copying and pasting code will never access fundamental knowledge. When copying someone else’s solution to a problem, you receive the solution but not the experience. You miss out on the hard work of arriving at a particular solution. You miss learning a skill.
Fundamental knowledge is portable. If you’ve attempted a problem yourself, failed at it yourself, and solved it yourself, you’re rewarded with knowledge that is no longer case-specific, but is instead case-agnostic. You’ve learned principles you can apply to future scenarios.
Solutions are rarely one-size-fits-all. To mold solutions to fit their context requires skill — and that skill can only be learned the hard way.
Seeking out the primary source, painting from life, without the noise of someone else’s interpretation or opinion, will always elicit the most generous lessons.
Practice Your Scales
When learning a piece of music, a pianist doesn’t just play it from start to finish and then repeat that process a thousand times. Weak spots have to be targeted. Gaps in knowledge have to be identified.
Otherwise, portions of the piece that are not well-understood invariably lead to lackluster, soulless performances (unmaintainable/brittle code) or outright mistakes and wrong notes (bugs).
Although blind repetition is an inefficient way to learn, targeted repetition can offer immense benefits, especially for a beginner. Experienced programmers may take for granted the fluidity with which they navigate Git or a bash terminal.
For the novice, however, repetition of these basic skills and obtaining a form of “muscle memory” frees up the programmer’s cognitive ability so that she may focus on higher-level engineering concerns.
So, if you’re new to a particular framework, let’s say Express.js, spend some time practicing your scales. Identify the core elements that this framework provides. Build something basic with them.
Get a server listening. Choose a port. Create a route. Receive a request. Respond with data. Then, finally, here’s the key: tear it down and do it again.
When a musician finishes playing a particularly tough section, they don’t dust their hands off and say, “well, I solved that one!”. The solution isn’t the point. The skill, the knowledge, and the facility is.
It may sound like a chore, but it’s actually embedding in you the muscle memory required to move onto higher-level thinking. To engineer something at a high level while stumbling through syntax errors is incredibly frustrating. Get these syntax missteps out of the way by practicing your scales.
This is how a professional violinist, after having practiced every scale in every key thousands of iterations, doesn’t need to worry about individual notes when it’s concert time. Armed with that muscle memory, she can instead focus on higher-level challenges. The phrase. The melody. The concierto.
Studies and Sketches
If you look at the journals of Leonardo DaVinci, you’ll find numerous studies and sketches of hands. Some studies even detail the musculature and bone. One might wonder: does he just have some strange obsession with the human hand? Why did he bother sketching all of these?
If you visit the Metropolitan Museum of Art in New York City, you’ll find countless paintings of still lifes. Bowls of fruit. Vases of flowers. In fact, visit any serious art school and students are painting these same items. Are artists trying to understand tangerines? Are they all budding botanists?
No. These are targeted studies. It’s not the fruit they’re trying to comprehend. Artists are trying to understand something more basic: light and color on form.
Similarly, my hope for beginning programmers (including myself!) is that our “sketchbooks” will be filled with studies on understanding a particular programming concept or problem. Small apps, experiments, cataloging our investigations into software engineering.
A Programmer’s Sketchbook
Any one of these curiosities can be explored by opening up a Repl or JSBin. Doing small studies of code can deepen understanding of larger projects.
When an artist sketches a hand, or a bowl of fruit, it’s not because these subjects are particularly interesting. Artists sketch to gain understanding in preparation for larger challenges. Small experiments to understand larger problems.
Look at the hands on the Mona Lisa. They’re perfect.
Portraits and Dependency Trees
I believe the core task for all creators (including programmers) is Composition. Literally: how do you put different elements together so that they relate in a cohesive way?
There are several strategies to do this (including hiring a product manager). One strategy is to build your piece from the base layer up. Begin with the layer that has the least dependencies. This could be your data models. If TDD is your vibe, this could be starting with tests.
When tackling a portrait, a painter doesn’t start with the eyelashes. The eyelash depends on the placement of the eyelid, which depends on the shape of the eye socket, which depends the subject’s bone structure, which rests on the angle of the neck and shoulders, etc, etc…
If any of these elements is drawn incorrectly, or is even slightly off-kilter, then your eyelashes are out of luck. Forget all that paint you layered on trying to coerce those eyelashes into working. Now it all has to be redone. Mistakes are multiplied down the dependency chain.
Layer by Layer
When building a full-stack application, get your data layer rock-solid. Write tests. Only then might you move onto routing, which will depend on that data layer. Test your routes. There’s no need to even open a browser yet. Confidence in the backend will allow confidence in the front end.
Hopefully, by the time you’re worrying about border radii on buttons, you’ll have a stack of application layers that have been built confidently upon each other, with green testing checkmarks all the way down. It pays to start with the bigger picture before the details.
Ultimately, even with all these strategies, even if you have the weight of a computer science degree, or the boost of a coding bootcamp, there’s no substitute for writing code. Composers compose. Painters paint. Coders code.
Coding, it turns out, is a sibling of the other arts. It’s a craft in itself and it can be practiced. I hope that, through deliberate practice and an appreciation for the arts, beginning programmers will be able to focus on fundamentals, hone their craft, and make work as great as their ambitions.