Efficient communication and trust

Let’s say I’d like to accomplish the following task with some code: I’ve got a list of names of fruits, and I want to know how many contain the letter ‘a’. Back in the day, this might have been done in assembly language, very low-level instructions which directly tell a CPU the details of which bytes to move into which memory locations and how to examine them in order to find out the answer.

A more recent way of doing this in a typical high-level structured programming language (like C#) would look like this:

int CountOfA = 0;
for (int i = 0; i < FruitNames.Count; i++)
{
   if (FruitNames[i].Contains("a"))
      CountOfA++;
}

Now we’re laying out for the computer a repeated sequence of logical steps to follow. What this says is, “Start with a variable to count the number of  ‘a’ fruits we find, and set it to zero. Then loop through the list of names, looking at each name in order, and if the name has an ‘a’, increment our counter.” This is very straightforward, the kind of code that developers write all the time. But to a non-programmer looking at this, it’s not necessarily clear what steps the code is carrying out or what the goal is.

Here’s a slightly more legible version, using a different syntax that many languages support:

int CountOfA = 0;
foreach (string fruit in FruitNames)
{
   if (fruit.Contains("a"))
      CountOfA++;
}

We’ve dropped that pesky index variable (the i), and the use of foreach makes it a little more clear what we’re doing. But it’s still 4 lines of code (6 if you count the braces) to ask the simple question, “How many of these fruit names have an ‘a’ in them?” Can’t we do better? Well, nowadays we can:

int CountOfA = FruitNames.Count(f => f.Contains("a"));

If you’re used to the older style of telling a computer to loop through a list, this syntax takes a little getting used to. It basically says, “Take the list FruitNames and count all the fruits f such that f contains ‘a’.” Which is only slightly more complex than posing our task in plain English.

But in addition to getting more concise, there’s something very interesting going on here in the way that we’re giving our instructions to the computer. We’ve moved from a syntax which tells the computer what steps to perform while somewhat obscuring the goal, to a syntax which just tells the computer what we want to know and omits the details of how to find that out. In doing this, we’re also in a sense being more trusting that the computer knows how to do what we want, so that we can just say “count these things” without explaining that this means examining each item and looking for an “a” (or, to go back to the assembly level, explaining how to move bytes around to accomplish this).

I’ve been thinking about this since my post about Leonard Bernstein conducting with his face. The essence of what a conductor does is to communicate his musical ideas to the orchestra as efficiently as possible; by “efficiently”, I mean simply, directly, and with a minimum of extraneous information. In the context of this particular performance, it turns out that the beat itself is largely superfluous, and Bernstein can tell the orchestra all they need to know through his expressive and well-timed facial expressions.

This relates to the above programming discussion in a couple of ways. First, like the FruitNames.Count example, the most effective way to let the orchestra know what he wants is for the conductor to indicate to them what the music should sound like, not how they should produce that sound. In rehearsal, for example, it’s often better for the conductor to sing a little of what he wants rather than trying to explain it in words, because that’s a more direct representation of the desired effect. Here, Bernstein’s face, free from any other distracting gestures, mimes the  character of the music.

Second, by limiting his instructions to conveying what the music should sound like, a conductor trusts his players – who almost certainly know more about technique on their various instruments than he does – to handle all the implementation details of how to make it sound that way. This kind of trust is important here because orchestral music-making, unlike computer programming, is a collaborative endeavor; the conductor who insists on dictating every last jot and tittle of a performance will often find that what he gets out of the orchestra is just exactly what he puts in, while the conductor who gives the musicians their share of responsibility gets the benefit of the sum total of all the artistry and years of experience sitting in front of him.

December 23, 2010   Tags: , ,