Duct Tape vs. Concrete: Thoughts on programming languages

When you're interested in programming languages, you'll notice that when people are talking about them, every once in a while a discussion about "real" vs. "scripting" languages flares up. This article is about two aspects of this discussion: First, it tries to explain the difference between those two types of programming languages (or at least the way I think about it); second, it's about the virtues and problems of these types of languages, and about my reasons for thinking that none of them will ever make the other obsolete (as some people think).

So what's a "scripting language"?

Given the amount of discussion and flamewars concerning the topic, you would assume that everyone agrees what's a scripting language and what's not.

You would be wrong.

What follows is my way of deciding what's a scripting language and what's not. While this way is consistent with the intuition of all programmers I've ever talked to about it, you might disagree. Even if you do, I hope the rest of the article is still helpful; either way, let's get going.

The way I define it, a scripting language is a language that comes with a big library of (more or less) useful, relatively high-level functions (e.g. opening a file isn't very high-level functionality; complete builtin regular expression support is). No big library of standard functions, no scripting language (though that library may be "external" in a way, as is the case with most Unix shells). Now this alone doesn't designate a scripting language; for example C++ comes with a big (some would argue too big) library of standard functions too, but I doubt anyone seriously thinks of C++ as a scripting language. But the key point is this: Typical programs written in a scripting language spend almost their entire execution time calling those standard library functions. Such programs are "duct tape" - they mainly glue existing functionality together.

By contrast, a typical program in a "normal" (for the purposes of this article, non-scripting) language implements most of its functionality itself - it builds its own foundation, it is made of "concrete".

Now, this is terribly flawed as a definition; the notion of a "typical program" in a given language is very hard to capture, and so is my pretty ad-hoc introduction of "high level" library functionality (what, for example, about complete GUI frameworks?). Still it is a sharper way to formulate the distinction than most people do, and more importantly, the two metaphors I introduced - while somewhat problematic, as all metaphors are - provide a nice, picturesque way of talking about the two types of languages that captures a lot of important details.

Typical properties of scripting/"normal" languages

Having established the distinction, we can make a few observations about what features are typical for languages of either type, and how they relate with the corresponding philosophy. Again, these are by no means necessary conditions, and most languages will not meet all of the criteria for their type.

A scripting language...

A "normal" language...

Again, as with the distinction between scripting and "normal" languages before, you may or may not agree here - but I hope it's clear what I mean.

Consequences and conclusion

As we see, most of these attributes are directly opposite to each other. This is no coincidence; the very features of scripting languages that make short programs easy to write make designing complex systems that have to adhere to rigid specifications hard. And the other way round, things like static typing which allow detecting a big class of errors already at compile time make programs longer and more difficult to write, because one has to be more precise about what exactly is meant.

It all boils down to what you're trying to accomplish - if what you need is a simple program that just reads a text file, does some simple processing and then outputs another text file, you're certainly best off with a scripting language. If you want to write an aircraft control system, however, a scripting language is out of the question. To stay by the metaphor: If you want to build up a stage for a concert, use duct tape. But if you want to build a concert hall, you'll need concrete. No sane person is going to build a concert hall out of duct tape - or do the stage construction with concrete. The two types of programming languages are fundamentally opposite - and as the way you approach small tasks like buying a bottle of milk at the supermarket is fundamentally different than the way you would plan a highway system for a whole country, so are the typical usage scenarios for these types of languages. No single methodology is best - different-scale tasks require different types of planning and thinking about them.

And if you think all that is pretty obvious, well, at least you now have a catchy metaphor that should come in handy the next time you're caught up arguing that distinction :)