At CodeMash Neil Ford gave a keynote about polyglot programming, a subject about which I’ve been thinking a lot — and a subject which I have a slightly different (and somewhat more pragmatic) set of opinions than Neil expresses.

But, at the moment I’m hung up on a throw away section of his talk which I think indicates a misunderstanding about the way language and metaphor work. A misunderstanding which is probably particularly common among programmers, but which goes to the heart of why I think software development is so difficult.

Niel takes exception with the notion that software development is software engineering saying something along these lines:

It’s not true. It’s a metaphor. In fact, it’s a ‘tortured’ metaphor. Software and engineering really are different. What we need is to get away from these metaphors, since they cloud the issue, and describe what it is we actually do.

He goes on to say a lot of interesting stuff about how engineering is different than software development, which is of course true. But I think that misses the point a bit. Methaphors aren’t supposed to be flat descriptions of fact. If I say “I’m as tired as a wet dishrag” nobody expects that they could measure my metabolic state against that of the dishrag and determine the “truth” of my statement. It’s true in a very different way. And I’m not just talking about creative language, or artistic merrit. Truth in this case is all about explanatory power.

Natural language is imprecise, analogical, and metaphorical — and after 4 years of philosophy, linguistics, literature, in school and 10 years of software development I’m convinced that these aren’t just surface traits of most language, they are the fundamental constructs from which all human language interactions are built. And, more than that I’m certain that this is actually a good thing, because the world is filled with things that we can only talk about that way. But I’ll get back to that in a second.

First, let’s dive into why I think Neil is wrong, and why I think his error is the kind of error that programmers are particularly prone to fall into.

Programming is both more abstract and more concrete than natural language. As Ocean tells us:

That there are no metaphors in programming, that there is zero ambiguity and every single line of code always has a definite, unambiguous, unarguable, and precise meaning has a very important consequence: integration is extremely difficult. Unlike poets who can take practically anything and throw it at the page and make it stick with a bit of jiggling and handwaving, a programmer must speak in a language that a computer can understand — ultimately, in 1′s and 0′s! And so it’s almost impossible to seamlessly combine programs to create new programs.

Every line of code has a specific well defined meaning. And unlike language that meaning is not the internal subjective representation of the code in the reader’s mind, nor a shared but nebulous social construct. It’s totally external and absolutely quantifiable. Code is defined by the way in which it will be parsed and executed by a pile of silicon.

Natural language is totally different.

One of the most influential philosophers of the 20th century, and very smart dude — Ludwig Wittgenstein — reminds us, it’s very hard to define many words even though everybody knows what they mean. The famous Wittgenstinian example is the word game which applies to things like ring-around-the-rosy, professional football, chess, World of Warcraft, hopscotch, and solitaire. The important thing to notice about this example is some games are played competitively, and others are not, some have well defined rules, others do not, some are frustrating and complex, others are simple and fun, some are professional, and others are done for pure pleasure.

You might suggest that there’s some core idea of amusement involved in all games, but that begs the question what is amusement? How could it be the same for children playing duck-duck-goose, football players at work, and chess masters practicing.

But the most important thing to remember is that even with all these “complications”, it’s obvious to everybody what we mean when we say game — even if they can’t provide an adequate working definition of “game” that actually covers all the things we commonly call games.

As I understand him, Wittgenstein, goes further to suggest that it is the lack of logical rigor, this tendency towards analogy and metaphor, this embrace of ambiguity that makes language useful. I think that’s very much true. Without ambiguity and metaphor we couldn’t communicate complex new ideas, and we couldn’t extend our base of knowledge from one area to another, and we would be entirely unable to communicate anything about huge swaths of human experience at all.

Back to programming. Program languages can’t express love, or disdain, there’s no such thing as irony. There’s no way to say anything meaningful about art or love or spirituality. It’s all concrete instructions that operate in a well known context. So, I see what Ocean is saying when he argues that programming is more concrete than natural languages.

But at the same time, I’m convinced that software development is all about creating systems that encapsulate various kinds of complexity. Another way to say that same thing is that software is all about building up layer upon layer of abstractions, and software debugging is all about the complex process of learning to traveling up and down the “abstraction stack.” And the terminology in software development is all divorced from any easy-real-world referent, “objects” aren’t physical, “stacks” and “heaps” don’t really “take up space” and memory “locations” are only metaphorical. The layers of metaphor requires to say the simplest thing about software development can be enormously daunting. In contrast with natural language it’s so easy to see the relationship between the word “pencil” and the real world object it represents.

So, software development is inherently much more abstract, and is often almost completely divorced from the concrete referents that make up everyday language. Which means it makes lots of sense to say that any kind of reasonable discussion of the the act of programming is ultimately less concrete than most natural language, as is any discussion of the code. And, really what else would you expect from a discipline build around building abstractions and encapsulation of ideas in executable forms.

Ultimately good programmers build up metaphors which provide layers of abstraction which are effective presisely because they offer a non-literal way of talking about the complex things that happen “undernieth” that layer. Take away the metaphors, and you won’t be able to talk about what you do. You won’t be able to explain what you do to other programmers, and you won’t be able to think lucidly about the problem domain and the code at the same time.

All this is the very long way round to saying that programming requires all kinds of mental tricks, and that ultimately talking about writing code is going to require metaphors. With all respect to Niel Ford, the problem is not that we use metaphors, it’s that we don’t understand how to use metaphors well. The more metaphorical our metaphors are, the better, because then they aren’t easily taken for flat descriptions of fact. As far as I am concerned, Software Development is like Engineering, but it’s also like washing windows on a skyscraper, playng chess, or trying to understand what language your teenage daughter is speaking.

Fundamentally I’m convinced that learning to do software development really well is about learning how to communicate really well. And communicating really well means working at the level of metaphor and analogy because the problems, requirements, and users of your system all operate at this level. It also means learning to translate that into code which expresses the metaphors that help people solve their problems in a medium (code) that has zero ambiguity, but to arrange that code into systems built around sensible — and easily communicated — metaphors.

In brief, natural language is ambiguous and nebulous while programming languages and software engineering concepts are concrete and unambiguous; and yet so divorced from physical reality that we lack anyway to talk about them unless we use even more abstract metaphors in natural languages.

That’s one way of looking at it, but I think that it has an overly pessimistic tint.

“Ambiguity” is not necessarily a bad thing. As I said in the article: “Without ambiguity and metaphor we couldn’t communicate complex new ideas, and we couldn’t extend our base of knowledge from one area to another, and we would be entirely unable to communicate anything about huge swaths of human experience at all.”

Metaphor (and therefor ambiguity) is at the core of how we learn and assimilate new information. And software development is about a lot of things, but it’s certianly about extending the conceptual scaffolding that we use to think — which means we need metaphor.

Here’s an example from science education. We know that electrons don’t orbit nuclei the way planets orbit the sun — but that metaphor connects with something we already know, and it provides a stepping stone to further understanding. If we tried to teach quantum states, orbitals and all of electron cloud theory at once schoolchildren’s heads would explode.

In fact, this isn’t just about the way kids learn science. It’s also true of the history of science. I think the whole pattern of scientific discovery is the about discovering, tweeking, and sometimes switching the metaphors (sometimes called paradigms) we use to process the way the world works.

So, I have a high view of metaphor and ambiguity. I understand why programmers in general don’t, but I think that very little could be done or discovered if we were only able to communicate in unambiguous code.

thank Zarkon not all developers *are* engineers but there are some, like you, that have an interest or education in humanities. As computers pervade almost every aspect of our lives more and more, I hope they (the linguists, historians, philosophers etc.) become more common in this field.

I say this for two reasons:

1. People with a technical reason have a tendency to think that everything is the way it looks, i.e. to believe what their senses tell them. They often forget that what counts is how the human brain interprets the input. And every human brain is different. So it’s not only important about *what* you are talking but also (probably more) *how* you talk about it. I think that was your main point too.

2. The process of creating software consists, as we all know, not only of actually writing code but to a good part in analysis, specification, testing and constant adapting. All this requires a fair amount of communication skills. Also, you are basically trying to *translate* the ideas of humans (the clients, the system designers, whoever) into the language of the computer. There is, as you and the people you cite point out, a distinctive mismatch between the two.

But IMHO it is misleading to think that in computer languages everything has a well defined meaning. For the computer maybe, yes, but after all these languages too were created by human beings and are written and read by human beings. Every human brain connects slightly different concepts with the same line of code. If code was totally unambiguous to everyone, why would we need so many different programming languages? Why do say that one language is more “expressive” than the other? Why do I have difficulties in wrapping my head around Java, but Python seems to fit my mindset very naturally?

So, my point is, although natural languages and programming languages may seem very different at first, their usage (by us) is very similar. We could not do otherwise, it’s how our brains work.