Sunday, December 10, 2006

A matter of bandwidth

My mom is a professional pianist, and she insists that for her music does not translate into words. However, when I listen to things she suggests, I find no problem in coming up with some lyrics or explanations for what I am listening to.

For example, I described the Spanish Dance no. 5 by Granados in terms of "people carrying out their duties, feeling honored in their obligation to do so, and yet... longing for the times of fun they desire, even though they know such entertainment is to be unavailable to them".

I commented this to Blaine a long time ago, and he urged me to blog about the explanation I came up with. I do not think it's perfect... it might be horribly wrong... but hopefully it is of use, and if it turns out to be defective hopefully a helpful reader will gracefully provide a proper correction.

So what is this ability, how does it work, and why could it matter? Well since structured language is left brain work, and emotions are right brain work, it seems to me that to put music into words or viceversa, one has to have good bandwidth between the two hemispheres. In other words, it appears to works best when there is a detailed map between certain areas of the left hemisphere the activation patterns of which result in certain words, and certain areas of the right hemisphere the activation patterns of which are caused by the music being listened to.

That leaves the matter of why does this matter at all. Well how am I supposed to feel that a program that I write is beatiful if I do not have a map between the part of the right hemisphere that evaluates beauty and the part of the left hemisphere that produces Smalltalk code? How could I tell, before writing it, that a certain approach is attractive or repulsive? How could I use this subjective sense of art to guide the rational process of writing programs, so that the proper decisions can be made when there are many choices available? Even more profoundly: how would I know if the options I have are enough, or acceptable at all as a whole?

I went to a concert a couple nights ago, and well... some of the compositions made me remember chimpanzees: when they talk with sign language, their sentences are very short and only use a few words. The longest sentence on record, spoken by a chimpanzee, has 14 words and it goes more or less like this: "orange orange give me orange give me orange give give me orange orange give me!". And in the same way that some of the compositions did not have elaborate musical phrases, each of the bars in the music sheet felt like a sentence consisting of a single word. Sad? Set of minor key chords. And what do the lyrics say? This: "... sadness this that...". Well, of course!

But the fact that the music is being literal towards the text is not what I found deficient. After all, great composers such as Ravel have produced very literal music such as the first piece of Sheherazade, called Asia. But what sets Ravel apart is that his musical phrases last for several seconds. His musical sentences have many words, and they are connected to each other artfully. If you have not listened Sheherazade, I'd suggest that you get a recording sung by Jessee Norman... most enjoyable.

And then, how does that relate to code, what I think is one of my arts? Indeed: I write code using a thesaurus. I look for the right words when I do not know them. I do not use selectors that denote meaning vaguely. I only write methods and classes after long consideration. I try to do most of the work, the design of the pieces so that the system has interesting emerging properties, in my mind --- before I press any key on the keyboard.

This, finally, brings me to the conclusion. If, in order to be artful, one has to use thinking bandwidth properly and efficiently, then how should we work to begin with? Let's play the renaming game once more. Think about how modern computers work, and what affects their performance. In short, the following bullets summarize most of the patterns we observe. The closer the information needed to carry out an operation is to the place where the operation is performed, then:

  • the less room there is to store such information, and
  • the faster the execution of the operations will become.
As you can see, this follows Zipf's law. You have a cpu, then you have registers, caches of various levels, RAM, hard drives, tape backups, and so on. In particular, we also have ethernet --- far removed from the cpu.

Then, let's rename things and see what happens. First, CPU becomes brain. Registers become the 7 plus minus 2 slots of scratch ram. Caches become our short term memory. Ram becomes our mid term memory. Hard drives etc become our long term memory. And, critically, we do not even have ethernet. We have these serial ports to communicate with our environment. Thus, if we are to be productive, we need to be truly efficient when communicating with our surroundings!

That immediately leads to concluding that most of the work should be done in our minds. When you first think of a problem, the worst thing you can do is to immediately write code. Because guess what: it will force you to think through your serial ports. Hacking things together, a calculated tradeoff between quality and speed, is caused by our first action: to write code we know to be deficient.

No, my friend. Think it all up in your mind, and when you have stable parts that tend to stay fixed as you design more and more of the solution, then write those parts only. Things that change should stay as close as possible to your cpu, in the 7 plus minus 2 scratch ram slots. It is almost obvious to state, but aren't computers inefficient when they thrash the paging file? Imagine now thrashing the paging file via a serial port. No way!

Finally, which language are you going to use through your serial ports? Something that makes you write tons and tons of syntax sugar? Of course not, because that will make you pervasively inefficient! It is bad enough that we have to communicate over a serial port. Why do we need to saturate the serial port and fool ourselves into thinking 100% average utilization is progress?

Excuse me, but have you seen the latest incarnations of generics? No, no, and one thousand times no. Why do I need to replicate everything I am thinking about over the serial port? That will also make me inefficient! Sorry man, I do not want a journaling thought system running on a serial port. Not only it is slow --- then it also has to have error correction. And when that is not enough, then I will also need version control of the external journaling thought system. All this overhead over an extremely low bandwidth connection causes me to waste time into things that have nothing to do with thinking about my problem!

So, my friend. Give me something like Smalltalk, where if I want generics I just implement a message and let the generic function be defined implicitly by means of polymorphism. That is so much cheaper and less costly! And yet, the access to the whole generic function can be accessed on demand via a menu item called implementors. That is it, no extra costs, and no overloading of my serial ports.

Then, with all the free time I will have when I do not have to stare at the serial port traffic completion dialog crawling from 0% to 100%, I will have the time and energy to do something much more valuable: make sure that the stable code that coalesces from the fog in my mind is both beautiful in terms of aesthetics, and beautiful in terms of its ability to withstand change. Only in my mind, with all the important things sitting in scratch ram slots and memory caches, I will be able to do that efficiently.

If code can resist change, then it is less likely that I will have to rewrite later on. And if I can find tiny code that is beautiful, artfully written in all the ways I described, then you can see what is going to be the development efficiency of version 5.0.

As the title of this post suggests, addressing these issues properly is a matter of bandwidth.

5 comments:

Jason said...

I agree with your language choice, but I completely disagree with your statements about "keep it in your mind".

To illustrate my opinion, imagine picking 5 of your friends/colleges whom you feel are very intelligent and have them play chess against the hardest computer you can find. The first time around none of them are allowed to redo, so they must work out the moves in their head. Then take the first five wins from each and average the times. Now do the same experiment again but this time they can redo as much as they want.

I believe you are going to see a *dramatic* difference in times. The will win *much* faster and more often when they can just throw a move out there, see the consequences and react to it, then trying to work it out in their head.

And this is why I choose smalltalk. In smalltalk I can half form an idea in my head, throw it out and see what happens. In some cases I can fix my false assumptions right in the debugger. Other times I realize the whole idea must be scrapped and worked out again, but this saves me so much time compared to working it out in my head.

Inside your head, with no "logic checks" from outside you could get quite far without realizing a major flaw in the over all idea. But a debugger popping up is a perfect wake-up call.

Now if we were using Java, then sure. You want to do as much as you can in your head because writing the code is so much pain and time consuming. Every idea you try out is going to take forever before you get to a point to see if it is viable.

Andres said...

Jason,

I disagree. For example, Kasparov may make mistakes like anybody else. However, as the rest of the best players in the world, he plays in his head and I am sure that he thinks much faster than he moves pieces. Thus, because I see that I am able to do so and that results are successful, I want to do the same thing when I work with Smalltalk.

I do not mean to say your approach with Smalltalk is bad or wrong. On the contrary, I believe it is beneficial to keep everything in the mind's scratch ram slots as much as possible and as long as it is beneficial. Your threshold may not be the same as mine, but both of us do the same thing.

Thanks,
Andres.

Jason said...

Right, but he isn't doing it all in his head because "he can" or "it is faster/better/more efficient" for him. He does it because there is no other choice. What separates him from most of us is that he is *capable* of doing something so hard and complicated as doing all the moves in his head. I have to believe that if he could take back moves that didn't work he could win the same games in 1/100th of the time even with all the false moves.

It is just that most humans need visual feedback to understand something. Another example is that the overwhelming majority of people can't just read a book on a new complicated subject and then know it. They must work it in a way that provides feedback.

But if you can hold everything in your head before you write a single line of code, then I must admit I am impressed. I just don't think this is the method to proclaim to people, because most of us are terribly inefficient at such a technique.

Andres said...

Jason,

Regarding Kasparov, perhaps somebody reading this will remember the appropriate interview and let us know :).

I started writing code when I was 10. And what I noticed back then, was that I would get some idea that would require a few lines of code. Once I got the idea, it was a matter of writing it down because it had already coalesced.

After 21 years of taking advantage of this, sometimes I get the idea of a framework and it also coalesces into code... but now, unlike when I was younger, I wait longer before I write it down --- because I have observed that, with a bit of thought, I can refactor and do more interesting stuff with it. This is what I meant before when I wrote that I tend to write down only what is stable and doesn't change any further.

I do not think this should impress anybody. It took me many many years of practice to be able to take full advantage of it.

What I think, though, is that although the method is the same, what is different is the threshold that triggers one to write stuff down. For example, Mozart used to hold the whole opera in his head and write it down on the last day. Sometimes, the orchestra received sheet music written in ink that was not dry yet. On the other hand, Beethoven went around with a notebook in which he wrote a multitude of pieces of music, and he used to write numerous drafts before he considered his compositions ready.

Both Mozart and Beethoven were great composers, regardless of the particulars of how they worked.

Thanks,
Andres.

Jason said...

Well it impresses me. I have always loved chess, but I just can't force myself to sit on my hands long enough to get so far in the move calculations. :)