The programming language I referred to in part one of this article is actually music notation; I’m a composer, and the ‘programs’ I write are pieces of music. It’s worth noting that, while I deliberately exaggerated the features of music notation which seem arcane or problematic from a programming point of view, music notation is an incredibly successful, complete and expressive language. Despite perhaps seeming daunting at first, children can pick it up incredibly quickly, and it easily takes root in one’s mind as a means of understanding, and a vehicle for expressing, music. Anyway, that’s a discussion for another day…
For the past year or so, I’ve been learning to program in the more conventional sense. I’ve mainly been using Swift, but have done some C and Python too, for good measure. It’s become increasingly apparent over time that there’s a huge amount of conceptual overlap between programming and composing. It’s fascinating, and not something I necessarily thought would be the case before I started learning. I’m going to give a rough overview of some of my observations below, and I might go into them in more detail in subsequent articles.
Music is a temporal art. In contrast to spatial arts which exist all at once, like sculpture or painting, music unfolds over time. This means that composing1 music requires a constant awareness of cause and effect, and context. A particular chord will have an entirely different effect depending on the context into which it’s placed; it’s affected by everything that comes before it, and will affect everything that comes after. Programming is no different. The value of a variable is a product of its context2; you must consider everything that may have influenced its state up to this point in your code, and everything that will be affected by changing its state. In both music and software, this can seem a simple thing to keep in mind at first, but it quickly and steeply increases in difficulty as the complexity or length of the project grows.
Composition almost always involves dealing with limited resources. If you write a highly complex and difficult piece, but only have an amateur group available to perform it, it may not work out too well. If you present a small chamber ensemble with a score for a full orchestra, there’s only so much that the group will be able to do, no matter what their skill level. Likewise, if you write a hugely CPU- and GPU-intensive application and it’s supposed to be run on smartphones, it’s probably not going to go very well either. When composing or developing, you must always ask whether what you’re creating suits the intended target, and be able to judge what kinds of compromises or changes must be made if it doesn’t. I think a good composer must be able to fully realise their musical goals within the established limitations for a particular piece, and a good programmer similarly should be able to create something that delivers on its goals within the constraints in which it is supposed to operate.
There are some notable differences between programming and composing, too. As stated in part one, the subjectivity of composition can be both a blessing and a curse. Performers are not computers; their executions of your music will vary slightly each time, and they can bring their own skill and interpretation to a piece. Sometimes they will enhance it beyond the composer’s initial intention, by virtue of their familiarity and expertise with their instrument. While a computer will faithfully execute your code the same way each time, including crashing bluntly at any mistakes, it cannot improve your code, nor will different computers ‘interpret’ your code any differently.
Another aspect in which the two activities differ is the latency of their respective feedback loops. Finding out whether a program works is so fast compared to what I’m used to. Compile it, test it, and you quickly have your answer (in most cases). Composition, particularly for acoustic ensembles, is very different. Unless you have a very understanding ensemble waiting in the next room, it’s unlikely that you can hear the results of your day’s work any time you want. There are of course computer-playback solutions, but for the most part they’re vaguely helpful at best. Instead, occasional workshops with performers, rehearsals, and concerts themselves are the only chances you get to truly test out your code.
So far my joint interest in music and programming has led to my first app, Tapt. It’s a music puzzle game, which I released in June 2016. It’s been a fascinating experience learning to program; I feel as though the conceptual overlaps I discussed here have been very beneficial in my understanding of it. I look forward to further results of combining the two.
This article was originally a talk I gave at Úll 2016, in Killarney, Ireland. It was a truly excellent event, and one of the highlights of my year by far. Úll 2017 is coming up in April, and I’d highly recommend going!