Design patterns: signs of languages’ weaknesses?

Sherman, set the wayback machine for 1957

If we dig back into history, we can find all sorts of patterns. For example:

Recurring problem: Two or more parts of a machine language program need to perform the same complex operation. Duplicating the code to perform the operation wherever it is needed creates maintenance problems when one copy is updated and another is not.

Solution: Put the code for the operation at the end of the program. Reserve some extra memory (a “frame”) for its exclusive use. When other code (the “caller”) wants to perform the operation, it should store the current values of the machine registers, including the program counter, into the frame, and transfer control to the operation. The last thing the operation does is to restore the register values from the values saved in the frame and jump back to the instruction just after the saved PC value.

This is a “pattern”-style description of the pattern we now know as “subroutine”. It addresses a recurring design problem. It is a general arrangement of machine instructions that solve the problem. And the solution is customized and implemented to solve the problem in a particular context. Variations abound: “subroutine with passed parameters”. “subroutine call with returned value”. “Re-entrant subroutine”.

For machine language programmers of the 1950s and early 1960’s, this was a pattern, reimplemented from scratch for each use. As assemblers improved, the pattern became formal, implemented by assembly-language macros. Shortly thereafter, the pattern was absorbed into Fortran and Lisp and their successors, and is now invisible. You don’t have to think about the implementation any more; you just call the functions.

Iterators and model-view-controller

The last time I wrote about design patterns, it was to point out that although the movement was inspired by the “pattern language” work of Christopher Alexander, it isn’t very much like anything that Alexander suggested, and that in fact what Alexander did suggest is more interesting and would probably be more useful for programmers than what the design patterns movement chose to take.

One of the things I pointed out was essentially what Norvig does: that many patterns aren’t really addressing recurring design problems in object-oriented programs; they are actually addressing deficiencies in object-oriented programming languages, and that in better languages, these problems simply don’t come up, or are solved so trivially and so easily that the solution doesn’t require a “pattern”. In assembly language, “subroutine call” may be a pattern; in C, the solution is to write result = function(args…), which is too simple to qualify as a pattern. In a language like Lisp or Haskell or even Perl, with a good list type and powerful primitives for operating on list values, the Iterator pattern is to a great degree obviated or rendered invisible. Henry G. Baker took up this same point in his paper “Iterators: Signs of Weakness in Object-Oriented Languages”.

I received many messages about this, and curiously, some made the same point in the same way: they said that although I was right about Iterator, it was a poor example because it was a very simple pattern, but that it was impossible to imagine a more complex pattern like Model-View-Controller being absorbed and made invisible in this way.

This remark is striking for several reasons. It is an example of what is perhaps the most common philosophical fallacy: the writer cannot imagine something, so it must therefore be impossible. Well, perhaps it is impossible—or perhaps the writer just doesn’t have enough imagination. It is worth remembering that when Edgar Allan Poe was motivated to investigate and expose Johann Maelzel’s fraudulent chess-playing automaton, it was because he “knew” it had to be fraudulent because it was inconceivable that a machine could actually exist that could play chess. Not merely impossible, but inconceivable! Poe was mistaken, and the people who asserted that MVC could not be absorbed into a programming language were mistaken too. Since I gave my talk in 2002, several programming systems, such as Ruby on Rails and Subway have come forward that attempt to codify and integrate MVC in exactly the way that I suggested.

Pages: 1 2 3 4

7 Comments

thleFebruary 10th, 2007 at 1:16 pm

What a long post!
I have not yet read all of the words in this post but I think I know what you want to say.
OO programming has been evolved a lot since its beginning.
Programmers have received a lot from language support. Things usually not perfect when it’s first created. People always try to improve the programming language.

Back to 80’s, the “Internet” concept has not yet popular, most applications just as simple as a simple app that runs on one machine. We did not have “Enterprise Application” that day. So, app is just about 3-5 lines of code, we don’t need Code Reuse.
But the life is not that simple, the demand on bigger applications has increased while Internet becomes more popular. As a consequence, app contains thousands line of code. Now we need Code Reuse, and that’s where Design Patterns starts its life.
When the demand for code reuse increases, programming languages has to change. In C, C++, we don’t have concept of Collection class, Event, …In more modern languages, e.g Java, vb6, we have those concepts. We even have some built-in design patterns in the language such as Iterator in Java. In recent language changes, we have more built-in patterns, e.g ASP.NET has MVC.

It’s obvious that languages and technologies always change in order to improve its weakness. So, is it necessary to say something is a sign of languages weakness? :-)

thleFebruary 10th, 2007 at 3:02 pm

When we identify and document one, that should not be the end of the story. Rather, we should have the long-term goal of trying to understand how to improve the language so that the pattern becomes invisible or unnecessary.

Even if we have a super good language, I am sure that we will still have patterns, as patterns are exprience reuse. it’s something like ” Hey, you want to sth efficiently, do it like me. I did it that way and … it works.”

Buu NguyenFebruary 10th, 2007 at 3:38 pm

What a long post! I have not yet read all of the words in this post but I think I know what you want to say

In case you are not aware, this post is not written by me, it is written by Mark Dominus at http://blog.plover.com/prog/design-patterns.html :-). I find this post very interesting thus I include the verbatim post here.

Back to your comments, while I can see where you are coming from with your arguments, I do not agree with many of them.

Back to 80’s, the “Internet” concept has not yet popular, most applications just as simple as a simple app that runs on one machine. We did not have “Enterprise Application” that day. So, app is just about 3-5 lines of code, we don’t need Code Reuse.

This is not entirely true. Complex applications which run across multiple machines (mainframes and interactive terminals) was not hard to be found in the 70’s. Enterprise applications (ERP for example) written in COBOL (created in 1959) also existed long before the 80’s and consisted of milions of LOCs. And code reuse, contrary to your thinking, was the hope of very early programmers (information about one of the oldest user groups about code reuse can be found at http://en.wikipedia.org/wiki/SHARE_%28computing%29)

In C, C++, we don’t have concept of Collection class, Event

Note that even in the Java language, we do not have these concepts as well. In fact, Collections and Events exist at the library or framework level, NOT at the language level. On the other hand, I agree that the concept of event and delegate exist in a .NET language like C# or VB.NET.

We even have some built-in design patterns in the language such as Iterator in Java

Not true, Java does not have iterator pattern built into the language, it only exists at the library level. However, in languages like Ruby and Python, Iterator is not necessary since closure can address the same need, or C# 2.0 with the foreach and yield keywords is kind of making the iterator pattern blended into the language level (although they are in fact just syntatic sugar and do not exist at the CIL level)

It’s obvious that languages and technologies always change in order to improve its weakness. So, is it necessary to say something is a sign of languages weakness… Even if we have a super good language, I am sure that we will still have patterns, as patterns are exprience reuse. it’s something like ” Hey, you want to sth efficiently, do it like me. I did it that way and … it works.”

Good point! I totally agree with this. Patterns will always be there simply because there is no such thing as a perfect language. Any language, at any level of abstraction, will have patterns associated with it, even if we can code by UML (or even voice :-)). After all, every pattern has a context, and the language itself is part of that context.

Phong BuiFebruary 10th, 2007 at 5:09 pm

At the first time I wrote a singleton class I had the question in my mind that was why doesn’t Java support a way to define a singleton class easier. It would be nice if I need only one keyword to mark a class as a singleton one. I wouldn’t need to handle of creating only one instance or safe-threading. When applying Template pattern to my framework, I recognized that Java seems to be biased this pattern since it has abstract classes.
Those things came and there was something appeared to me that design patterns are well-known chess-positions. Software development is a chessboard and programming languages support fundamental things (i.e move, capture, checkmate, etc…). Those things help programmers play on this chessboard. Let’s say if programming languages had supported resolution for each particular chess-position the player would have proceed only one step to solve the game (instead of doing a number of steps) when it is falling to a predefined chess position.
Stop the chess game above and back to software development, it would be nice if programming languages could enrich them by building-in some well-know design patterns. So I prefer addressing this way rather than calling “languages’ weaknesses” although both result almost same?
We could somehow count the number of chess-positions so far but I cannot count it up to next 5, 10 years or even next 5 minutes since we’re living in a very innovational world. Deep Blue machine was built-in more than 2 million chess-positions but nobody correctly say that’s enough and all for now.

Tai has pointed out some interesting information regarding to design patterns. However, I bet the design pattern is more than code reuse. Design patterns solve design problems. Code reuse is one of design problems.

I almost agree with Buu what you’ve commented on Tai’s notes here. However, for me a programming language is not only syntax but also library. Behind syntax are built-in libraries. Fully separating library from a programming language isn’t somewhat precise.

thleFebruary 11th, 2007 at 6:50 am

I was just want to point out that the increase demand on code reuse, and speedy developed apps; and the languages & technologies has evolved a lot for that demand.
As I said, I did not read thru the post, and did not notice all the details. The post wanted to claim the languages, not the libraries.
Let’s separate C# from Base Classes Library and use it alone, that will create another Microsoft or Sun.

Another point, OO programing rules the game now. Wanted to claim the language, let’s claim OO programing first.
I dont subject to something that will beat OO programing. If there is another better, I will use it. Let’s wait, who knows! :-)

Buu NguyenFebruary 11th, 2007 at 7:15 pm

You have a very interesting comparison, anh Phong; however, I am not quite sure I understand what you aim at by this comparison. Do you want to say that because there are so many chess positions that there should be no limit to the number of patterns? (If this is what you mean then there is at least one flaw: the number of chess positions is finite, while the number of patterns is not.) If not, can you elaborate your argument further?

I bet the design pattern is more than code reuse. Design patterns solve design problems. Code reuse is one of design problems.

I agree. Design pattern is meant to create high-quality design. Depending on the architectural constraints of a particular project, a high-quality design usually mean performance, extensibility, maintainability, reusability, reliability, usability and so on.

However, for me a programming language is not only syntax but also library. Behind syntax are built-in libraries. Fully separating library from a programming language isn’t somewhat precise.

Depending on the topic that we are discussing about, it may or may not be necessary to distinguish the semantics of a programming language from its built-in libraries. For this particular topic (design patterns are signs of programming languages’ weaknesses), it’s worth making the separation.

Buu NguyenFebruary 11th, 2007 at 11:57 pm

…point out that the increase demand on code reuse, and speedy developed apps; and the languages & technologies has evolved a lot for that demand.

That’s true, programming languages and technolgies evolve to help us develop more complex software in less time and reusability is one of the objectives

Let’s separate C# from Base Classes Library and use it alone, that will create another Microsoft or Sun.

Hmm, what do you mean? :-)

I dont subject to something that will beat OO programing. If there is another better, I will use it. Let’s wait, who knows

I guess I’ll elaborate this a bit when discussing about C# 3.0 :-)

Leave a comment

Your comment