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

June 17, 2006

Notation vs. Paradigm

Recently, I've been taken with the idea of programming languages as notation. When most people look at a programming language, they see syntax and possibly an underlying paradigm. I see the same, I just find the idea that each language also provides a unique notation for expressing ideas quite appealing.

Lately, I've been thinking about how notation relates to programming paradigms. In order to explore this topic, I need to begin with some definitions. Most programmers are familiar with one or two programming paradigms: the object paradigm, the functional paradigm, the generic programming paradigm, and so on. But, if asked, most could not explain what a paradigm is. The third definition of paradigm on Dictionary.com seems to fit our needs the best. This way of viewing reality definition definitely fits the way programmers apply programming paradigms.

The term notation is not used as much in our industry, so I would suggest the second set of definitions from Dictionary.com as being closest to what I mean: a technical system of symbols used to represent special things.

The key difference between these two is that a paradigm defines how you think about problems and solutions, and a notation defines how you write about problems and solutions. This leads to the obvious (to a programmer) question, are these two concepts completely independent. It's probably safe to say that the answer is no. (The dot notation used by many languages to make method calls is not very useful in a non-object oriented language.)

The next obvious question is how separate are they. Most of us a familiar with at least a couple of different object-oriented languages, since that is pretty much the dominant programming paradigm right now. Many of the differences between these languages are not about paradigm, but about notation. We often argue about:

  • "." vs. "->"
  • pointers vs. references
  • null vs. 0
  • garbage collection vs. RAII
  • messages vs. methods
  • interfaces vs. abstract base classes
  • inheritance-based polymorphism vs. duck typing
  • static typing vs. dynamic typing

The interesting thing is that in most cases, replacing one of these with the other would not change your ability to program with the language. None of them have anything to do with the paradigm. (Although I've heard people in some groups claim that a language can't be object oriented without: garbage collection, exceptions, message passing, or strong typing.) In reality, you can do object design and programming in assembly language if you choose. The problem is that the notation of assembly language is not well suited to the paradigm.

The key to a good notation is that it simplifies writing about your problems and solutions. As such, it may be worth suggesting that different notations may be useful for different problem domains and kinds of solutions. I also think that some people are more comfortable with some kinds of notation than others. Although we try not to admit it, often the choice of notation is more a point of personal preference (or habit) than of technical merit.

This is not to say that all notations are equal, some notations are more powerful or clearer than others. Even in the procedural paradigm, C is usually considered clearer than assembly. A really good example of the differences in notation is the implementation of a 2D matrix. In a language that supports matrices natively, you can add two matrices like this:

C = A + B

and multiply two matrices like this:

D = A * B

In some OO languages, you can build a matrix class and (with operator overloading) get an equivalent notation.

C = A + B
D = A * B

If the language doesn't support operator overloading, you might end up with a notation that looks like this:

C = A.add( B )
D = A.multiply( B )

Without some kind of support for user-defined types, the notation gets increasingly messy.

Now, if you do a lot of work with 2D matrices, the first notation is going to be important to you. It requires less typing, it is clear, and it's mostly what we all learned in school. If you haven't had need of 2D matrices since your last math class, the difference in notation will not be important.

This leads back to an important point. Notation determines how you write your solutions. It is possible to write object-oriented code in C. Unfortunately, the notation available in C does not support OO comfortably. The development of C++ (and Objective C and Java) made OO more popular by supplying the notation needed to support this paradigm.

The competing concepts of expressiveness and clarity are part of what defines a notation. Any time you are confronted with a new notation, the clarity point is driven home. A new notation is more difficult for you to use than one you know. On the other hand, as you become more comfortable with a notation, the expressiveness concept becomes more important. A good notation must be clear enough that new people can learn to use it, yet expressive enough to solve real problems.

Different languages make these tradeoffs in different ways. Just as importantly, different people have different tolerances for where they will accept the tradeoff. Some people prefer expressiveness in a language. They take the view that they will only be novices for a short while compared to the time they use the notation. These programmers are willing to trade a steeper learning curve (less clarity) for the power a more expressive notation gives. At the other extreme are people who prefer clarity over expressiveness. These people assume that most people will not be able to handle a very expressive notation. To this group, a simpler, clearer notation is more important than expressiveness because more people can understand it more readily.

Notice that this concept is independent of paradigm. Each notation in each paradigm makes these (and other) tradeoffs differently, based on the experience and biases of that language's creators. So, the next time you find yourself in a fight over which language is more object-oriented, you might want to consider if you are arguing paradigm or notation. It may not stop the holy war, but this viewpoint might at least confuse your adversaries.(<grin/>).

Posted by GWade at June 17, 2006 02:40 PM. Email comments