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 (unfortunately, I can’t play anymore), 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
(To view a score, it can be found here)
2) G major Prelude from Cello Suite No. 1
(To view a score, it can be found here)
Many of you may be familiar with these pieces. They’re often used as background music for commercials, as well as occasionally used in movies. They’re nice, right? Simple, pleasant to listen to, some might even say perfect. Beneath that facade however, lies a carefully constructed tapestry, with each note (yes, every single one) serving it’s own purpose in the greater scope of the work.
Let’s take the first piece. The first four bars (ending at 0:20 in the corresponding video above) are composed accordingly to introduce the key of the piece to the listener and ground their ear in that tonality. Additionally in this piece, the regular arpeggio configuration establishes an expectation of a regular pattern for the listener. From there, the piece moves through more than a handful of keys (or at least suggest them), though this meandering is largely 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 proceeded by the only arpeggiation which breaks the established pattern, serving both an expressive purpose and 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 of it 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. However 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 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. 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 of harmonic voices.
This 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 an expressive and/or functional purpose, just as a coder may add an additional method or class to a program to give necessary functionality that could not otherwise be defined in the other parts of the program.
For me in my coding journey, I’ve been striving to write code like Bach writes music (the difference being that my code tends to have several drafts, whereas Bach was a goddamn genius and probably wrote both of those pieces in a combined 30 minutes). My goal is to make my code simple but complex, elegant but clearly structured, organized but not rigid. Although coding is new to me, I find my aforementioned goal to be guided immensely by my musical education. When I’ve run into an error, 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, or about beginning to write a new piece of music, and how the planning involved is eerily similar to that of writing code for a lab or new program.
I haven’t composed anything in close to 6 years now, and never really expected to do so again. However, it’s refreshing now, to be composing code.