This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

April 14, 2006

A different view of programming languages

I've been thinking lately about the differences between programming languages. Over and over again, we see religious wars over what is the best programming language. Lately, we've also seen a lot of comparisons that look at particular classes of languages.

  • Object-oriented vs. procedural
  • Dynamic vs. static

I have always had a kind of fascination with programming languages. I have studied several languages over the years, some of them very different than others. Over time, I tended to seek out languages that were somewhat different than the ones I already know. Alan Perlis is often quoted as having said:

A language that doesn't affect the way you think about programming is not
worth knowing.

When I first ran across this quote, I felt that it explained much of my fascination with programming languages. Each language I've learned has taught different approaches to solving problems, different ways of thinking about modeling the world, or provided different tradeoffs in terms of safety and efficiency. Unlike many language zealots, I've never really felt that one languages was best for all problems. This doesn't mean that I don't have some languages I like more than others, or that I won't get into a language discussion. I just prefer to have several options instead of just one.

Lately, all of the hoopla about Domain Specific Languages (DSLs) has got me thinking about this concept some more. After quite a bit of thought, I've realized that programming languages provide something else that I hadn't really thought much about. If you ask most programmers what the important attributes of a programming language are (and strip out all of the language-bashing and such), you would probably get a list something like:

  • Paradigm: (object-oriented, procedural, functional, etc.)
  • Strictness of types
  • Compiled vs. interpreted
  • Syntax

But, there is something so fundamental that we tend to overlook it. A language provides a notation for expressing solutions. By notation, I mean something a bit more than raw syntax. A notation that fits the solution and problem space, makes solving the problem almost effortless. If the notation doesn't match the problem space, the solution will be much harder.

One of the best known examples of the effect of a useful notation is the change in mathematics when Roman Numerals were replaced with decimal (positional) notation. Before a positional notation became wide-spread, arithmetic with large numbers was extremely hard. Most people who needed the ability to add, subtract or multiple large numbers used lookup tables. Very highly trained experts worked out the math to build the tables.

After a positional notation became more common, arithmetic with large number is something anyone can accomplish. In fact, we teach the techniques to multiply two numbers of any size to elementary school children. We can do this not because kids today are smarter than Roman children, but because we use a superior notation.

This applies to programming languages as well. In problems which require manipulation of matrices, the amount of syntax used in the manipulation can have a major impact on the ability to express a solution. If you need to scale a 2D matrix, which is a better notation?


for(int i=0; i < num_rows; ++i)
{
for(int j=0; j < num_cols; ++j)
{
matrix[i][j] *= 2;
}
}

or

matrix *= 2;

Ultimately, the implementation must do something similar to the first case to make the either solution work. But, in the second notation the unnecessary details are hidden. The first one takes a little time to read and understand before you can say for certain what it does. The second is mostly understandable at a glance. Does that make the second one a better notation? It depends. If you need to do a lot of matrix math in your programs, I think the answer would be yes. If you never do any matrix math, the notation is of no use to you, so there is no sense in cluttering your language with it.

Fundamentally, this is the reason why we need different programming languages. Some solutions are expressed better in one notation than in another. Some languages allow the programmer to adapt the language's natural notation to fit the problem.

I believe that the recent interest in DSLs results from a desire to express our solutions in a better notation. This idea has been strong in the Unix world for years where little languages are used to solve numerous problems. The Unix world is also a good place to see the importance of designing your notation carefully. It is also important to see these DSLs for what they are: a way of reducing the noise in our programs by using a high-signal notation to express a solution.

So to paraphrase Perlis:

A notation that doesn't simplify solving problems is not worth learning.
Posted by GWade at April 14, 2006 10:25 PM. Email comments