Thoughts on programming language expressiveness
February 21, 2011
“From one gut feeling I derive much consolation: I suspect that machines to be programmed in our native tongues — be it Dutch, English, American, French, German, or Swahili — are as damned difficult to make as they would be to use.” — E.W. Dijkstra
If you look around at the world of programming languages, you’ll notice that much hasn’t changed in the last 20 or 30 years. The scenery has shifted, sure — new languages have come into vogue, others have gone out of style — but the fundamental paradigms of programming language design haven’t evolved much since Smalltalk. Consider, for instance, that C-style object-oriented programming still dominates the software industry — whether it be C++, Objective-C, Java, C#, or ECMAScript and its progeny. This family of languages has been dominant for decades and shows no signs of relinquishing its dominant position any time soon. The question is: Why? On one hand you have C, essentially a glorified assembly language, so impoverished in its expressiveness it takes myriad lines of code to say anything. And on the other hand you have “modern” languages like Java and C#, so dominated by rigid ontological structure and type systems that they have become a kind of bureaucratic nightmare.
These are the primary tools that we as programmers and software developers use to express our ideas, so one would think that we’d clamor for something better. One would think that we’d desire languages that are far more expressive and far less-constraining; tools that allow us to express our ideas as we think them, rather than as the computer requires them to be expressed. Programming languages where the computer better understands what we mean, not just what we say.
One would think …
Making good software is hard. Part of the reason it’s so hard is that the tools we have for making software are still pretty darn awful. Writing enterprise software in, say, C++, is akin to attempting to write Anna Karenina using a third-grader’s vocabulary. You can tell the story, but it’s going to take a lot more words to say it.
The most expressive languages on the planet are natural human languages. We have something to learn by studying them. Of course, this doesn’t mean that the ultimate panacea for our software development woes is to start programming in plain English. I agree with Dijkstra on this: such is a path fraught with disaster. Languages that historically have attempted to walk this path have never gained much traction. AppleScript, for instance, (like HyperTalk before it) has its adherents, but most find it too cumbersome and verbose to bother learning. There is a fine line between expressiveness and tedium.
Instead, perhaps what we need is more of the flexibility and expressiveness of natural language to find its way into programming. Take Perl. Some people call Perl an abomination. I’m not going to argue. But there are a few design principles that Larry Wall got right:
- Say it how you want to say it: Just as in natural languages, in programming languages there should be more than one way to say the same thing. I say, “take a walk,” you say, “go for a stroll.” They mean the same thing, and since programming is ultimately an act of describing behavior (we’re not writing poetry), meaning is what matters. Some may argue that this kind of “polyexpressiveness” impedes software maintainability. If one programmer solves a problem with some form of obscure syntax, the next programmer may have difficulty understanding it. There are at least two counter-arguments: One, the constraints of a programming language should not define your chosen best-practices. Let languages be about freedom; let the community or development team decide how these freedoms may be exercised. Two, the gain in productivity afforded by being able to think about a problem in multiple ways more than offsets loss caused by having to learn syntax. Learning new things is good for you.
- Ambiguity is not a sin: There is power in ambiguity. Consider, for instance, the argument that more (dynamically-typed) programming languages should support pronouns – namely, the ability to refer to the result of a previous calculation as “that” or “it.” Perl is one of few programming languages that supports pronouns, the famous (or infamous), $ and @. Pronouns keep local code DRY while simultaneously allowing the programmer to better focus on ideas instead of spelling and syntax and unnecessary naming. Nevertheless, they should not be included at the cost of readability. I’m no fan of Perl’s use of implicit pronouns (called “topicalization”). They largely render code unreadable. But explicit pronouns are just fine.
- Support inevitable divergence: As Wall writes, “Because a language is designed by many people, any language inevitably diverges into dialects. It may be possible to delay this, but for any living language the forces of divergence are nearly always stronger then the forces of convergence.” Why not build support for dialects into a programming language? It promotes experimentation, community contribution, allows for dialects to flourish without detracting from the language core. Sticklers for standards may find this appalling, but if dialects are modular – like plug n’ play domain specific languages – there’s really no good reason not to like them. The best ideas in new dialects may soon find themselves part of the language standard. E4X, for instance, started out as a domain-specific ECMAScript dialect in WebLogic that now finds (fairly) wide support.
Larry Wall is a linguist, so while that may not have enabled him to be the world’s most popular programming language designer, it did allow him to approach language design from an entirely different perspective. We need more of this. The challenge with programming languages today is that they’ve all been designed solely by programmers and computer scientists, people far too enmeshed in existing paradigms to think differently. And we desperately need to think differently. Because when it comes to programming languages, I think we can do much, much better.