One of my assignments was to read and annotate Guy Steele’s Lambda The Ultimate Imperative (library.readscheme.org/page1.html). I’ve read the paper twice and opened up an editor to write about it five or six times. As I read the paper, I knew it was teaching me something that was going to have a lasting effect, but somehow when I sat to write about it, the only memories I could summon were the mechanics of Scheme (which the paper is written in/using).
I’ve been learning Scheme in parallel to reading this paper, and I’ve definitely felt a lot of "schemisms" snap into place as I read. But I know that simply learning the language isn’t what this paper is about. It’s just so hard to separate learning the language from discovering the purity and simplicity of what Steele is demonstrating. The beauty of Scheme is that there’s hardly anything to it. To see Steele effortlessly implement programming constructs on top of this near-nothingness drives home the power of minimalism.
So, now I realise that, above all else, it’s a fascination with minimalism that I’ve brought home from Illinois. Apparently, I’m not the only one.
If minimalism is good, then what’s the opposite of minimalism?
When I studied music composition with Kamran_Ince, there was one thing I always knew he was going to say when I walked into his office with a new composition. He was going to tell me something like, "You’ve got such a great idea here. Why do you have to run away from it so quickly? You didn’t develop it. We didn’t even know it happened!" I would literally walk in to the beginning of a lesson knowing this was going to happen, and yet it would happen every time. It felt a little like not being able to spell "FBI" or like being given the answers to a test and then failing it anyway.
Though he wasn’t necessarily trying to encourage me to write music in the style of a minimalist, the lesson was in fact about minimalism as a craft element. And, if minimalism is good, then what I was bringing to Kamran each week was its opposite. Lots of good ideas, jammed into a very tiny temporal space. The end result was a jumble of intelligent thoughts, stepping all over each other so that none were ultimately recognizable. Have you tried to use JDNI? It was probably the musical equivalent. In the software world, this has the effect of both muddying up what is already there, and creating an environment that is unfriendly to extension and change.
I don’t know much about the thing called "minimalism" in art-forms other than music. But, in music, one of minimalism’s key features is that of emergence. When players are making repetitive and rhythmic sounds, a la Terry Reilly, it’s almost never the written notes and rhythms that are interesting. It’s what happens when they’re all played together by imperfect humans. It’s the slow and subtle phase shifting, and then the musicians’ subtle reactions to the phase shifting.
Scheme obviously creates an environment that encourages emergent behaviors. In fact, the whole point of Lambda the Ultimate Imperative (LtUI) is to show that Scheme can be an imperative language, without changing Scheme and without "shoe-horning" Scheme to awkwardly meet the imperative critera. LtUI happens to be written by one of Scheme’s designers, but there’s no reason you or I couldn’t have written that paper (other than my age at its time of publication).
So, back to Kamran Ince. He was trying to teach me not just to keep my music simple so I could develop ideas. He was also trying to teach me to create powerful ideas. You can’t write music the "Kamran Way" while making timid gestures. If you’re going to let it all hang out with an idea, it better be strong.
And, with music, I think it’s a lot more apparent (than in programming) that you can’t start with an idea that doesn’t provide a platform on which to build a piece. For a patently contrived example, listen to this. It would be possible to build a piece of music on something that sounds so final, but it would sound strange and intentional. While the temporal element is missing, an extremely rigid language or an API that is too large and complex can produce the same effect of stunted idea growth in software. For (potentially inflamatory) example, if a method of an object can only accept parameters of a certain class, my freedoms are extremely and intentionally limited when using that object.
So, "good minimalism" doesn’t require simply that we "be minimal". It requires that we correctly balance substance and space in a way that encourages evolutionary growth. It is possible to be minimal and rigid, which will lead to small ideas that can’t be developed any further. This is rarely what we want. Minimalism is one of these words (like "simple") that sound easy to do but actually require a lot of practice to get them right.
I see now that Lisp and Scheme aren’t different because of their minimal syntax or their dynamism. It’s the fact that they "get out of the way", providing the right balance of mechanism and policy to allow their users to continue to evolve in the direction that nature selects, while not being so austere that wheels are necessariliy being reinvented every day. This is what has drawn me to Ruby (and Smalltalk and Scheme) and away from the likes of Java and C#. Not dynamic vs. static typing or compiled vs. interpreted environments.
Many of the arguments for and against these minimal environments seem to boil down to the Mechanism vs. Policy tradeoff. But, I’ll leave that for a later post.