Before I get to the bulk of this thread, I’d like to preface it with a little bit of background about myself. My college education is in music, with a BM from the Eastman School of Music in Viola Performance, the first two years of which I spent studying composition. In addition to my time at Eastman, I also studied composition at the San Francisco Conservatory for a year and a half.
Coming from a musical background, coding was very foreign to me. Aside from what little I knew about computers by using them to browse the web or make use of various types of software, my knowledge of what made those things work was next to nothing. To my (pleasant) surprise, I’ve found that, in general, learning and writing code is not dissimilar from learning and writing music.
Consider the following pieces by J.S. Bach:
1) C major Prelude from Book 1 of the Well-Tempered Clavier
2) G major Prelude from Cello Suite №1
Many of you may be familiar with these; they’re often used as background music for commercials, as well as in movies. They’re nice, right? Simple, pleasant, some might even say perfect. Beneath that façade, however, lies a carefully constructed tapestry, with each note (yes, every single one) serving its own purpose in the greater scope of the work.
Let’s take the first piece. The initial four bars (ending at 0:20 in the corresponding video above) are accordingly composed to introduce the key of the piece to the listener and ground their ear in that tonality. Additionally, the consistent arpeggio configuration establishes an expectation of a regular pattern for the listener. Continuing from this opening, the piece moves through more than a handful of keys (or at least briefly suggest them), creating a sense of increasing tension as a return to the original key is avoided. For all its show and drama, however, this meandering is largely and simply a prolongation of the dominant (for those unfamiliar with music theory, a lot of western music revolves around the relationship between tonic and dominant). Somewhat astoundingly, this prolongation of dominant doesn’t actually fully resolve until the very last bar of the piece, which is also preceded by the only arpeggiation which breaks the established pattern, serving an expressive purpose, as well as a functional one, by cueing to the listener that the piece is coming to an end.
I’ve played the second piece a number of times and am intimately familiar with it, so I’ll try to keep my discussion brief (if you’d like the longer version, feel free to message me!). In a lot of ways, the structure is very similar to the formerly discussed: the first four bars (ending at 0:15) serve to establish the key, followed by a long prolongation of the dominant, and ending with a new configuration before the final chord. Unlike the regularity of the C major Prelude, this one has a much more improvisatory nature, breaking the established pattern several times before the final few bars, resulting in a greater sense of drama and expression, though not without maintaining organization and coherence.
In discussing these pieces (and many others) with one of my teachers, Ricardo Zohn-Muldoon, he made a distinction between a well-written piece being “simple, not simplistic”. His point (or at least, how I interpreted it) is that “simplistic” implies something that lacks depth (think Hot Cross Buns or See Spot Run), whereas something that is “simple” has a level of complexity, either inherent or potential (not the most thorough analysis, but think Beethoven’s 5th). The Bach pieces above are perfect examples of this concept, as in addition to formal complexity, each note in the configurations are carefully chosen according to the rules of counterpoint, the purpose of which is ultimately to maintain clarity and individuality of harmonic voices.
Aside from some of the specifics, a lot of the ideas above sounds quite similar to writing a well-built program, doesn’t it? The goal is to make your code simple and easy to understand, while at the same time providing the necessary complexity and functionality that the given program requires. A well-built program strips away excess and provides only the essentials, just as the two preludes maintain only what is necessary for the piece to be expressive without sacrificing coherence. Indeed, Bach only strays from the established pattern throughout either piece for a specific purpose, whether it be expressive, functional, or both, just as a coder may add an additional method or class to a program to give necessary functionality that could not otherwise be defined elsewhere.
Since I started learning to program a little over a year ago, I’ve been striving to write code like Bach writes music (an almost assuredly impossible ideal, I know). My goal is to make my code simple but complex, elegant but clearly structured, organized but not rigid. Although working with code is still relatively new for me, I find this pursuit has been and continues to be, guided immensely by my musical education. When I’m debugging, I often think about all of the hours of practice I spent trying to learn certain passages in various pieces and the process I used to tackle them. Similarly when starting a new project or building a feature, I reflect on the process of beginning to write a new piece of music, and how eerily similar the planning involved is for both.
The more people I’ve met in the ‘programming world’, the more fascinated I’ve been with the differences in people’s backgrounds and what insights they bring to the table, ones that often feel fresh and interesting. Along with a plethora of reasons, continuing to meet and work with such a diversity of people has been one of the better parts of this career so far, and one to which I hope to contribute as much as learn from.
I haven’t composed anything in close to 6 years now, and never really expected to do so again. Now, instead of composing music, I’m composing code. And it’s a great feeling.
Originally published at saurookadook.github.io.