Stephen Freeman Rotating Header Image

March, 2005:

It's about syntax

Martin Fowler has stepped into the fray and written about “dynamic and static typing”:http://martinfowler.com/bliki/DynamicTyping.html. I’m know he understands it, but he hasn’t emphasised the difference I find most significant, the syntax. This has been blogged about quite a few times in recent months, but here’s another one anyway.

The interesting dynamic languages don’t have much built-in syntax: in Smalltalk it’s some punctuation and how to send a message, in Lisp it’s some parentheses. The bulk of the day-to-day language is in the standard libraries. What this means is that you write an application by extending the language into your domain and then programming in that new language. For example, in Smalltalk using a boolean looks like:

aBoolean ifTrue: [ doSomething ]

in my application I might write:

aDocument ifIsComplete: [ notifyEveryone ]

Notice the difference? Neither can I. There’s one consistent programming model throughout the code. Coming from conventional languages, it takes a while to realise that even Booleans are objects with methods like _ifTrue:_. This consistency is especially nice when working with collections:

aDocument allNodes do: [aNode| aNode removeText ]

as against:

Enumerator allNodes = doc.getNodes().enumerator();
while (allNodes.hasNext()) {
  ((Node)allNodes.next()).removeText();
}

The first expresses that I want to remove text from all the nodes. The second clutters that intent with type information and, more importantly, makes me think at two levels: objects with methods, and process flow instructions — it’s overhead.

It’s hard to emphasise enough how much clearer you can be when your code describes the solution, not the implementation of the solution.

h4. Building language dynamically

Where this approach flies is that objects can respond to requests they haven’t seen before. This is not a technique to be used all the time, but sometimes it’s the right thing to do. Unlike in static languages, in dynamic langauges I can call a method that has not been defined on an object. The usual response is to call a special method (in Smalltalk _doesNotUnderstand_) that by default will throw an exception. As a programmer, I can provide my own implementation of this method that will attempt to interpret the call.

Here’s a small example. In Smalltalk I can say:

aDocument head title set: 'new page'

where _head_ and _title_ are not predefined methods. When a node in a document receives a message it doesn’t recognise, it translates that into a search of its child nodes and returns the first one that has the same name as the message. _This is invisble to the client code that is navigating the document._

In, say, Java I’d have to predefine a whole set of node types, matching the document schema, to write:

document.getHead().getTitle().set("new page");

To handle a different document structure, I would have to change the navigation code. Alternatively I could write something like:

document.getNode("head").getNode("title").set("new page");

or

document.node("/head/title").set("new page");

which means breaking into another syntax (node names or the path expression). I’m juggling two programming environments, Java and something dynamic based on strings, to get the job done.

Once again, the dynamic nature of a language such as Smalltalk and the consistency of its structure means that I can write code about manipulating document contents, not code about manipulating an implementation of a document.

Technical bankruptcy?

Darren Hobbs “writes”:http://www.darrenhobbs.com/archives/000624.html that almost no rewrites have any technical merit. This is often true, but not always. There are many working systems out there which are stable but just too hard to change — which makes them a threat to the survival of the business. All those other reasons that Darren mentions, such as cost and politics, might well be sufficient justification for change from the business’ point of view. Finally, it’s worth remembering that often what keeps these rewrite candidates alive is an unholy collection of scripts, utilities, and other systems to manage their relationship with the rest of the world.

One way to think about a rewrite is that the interest payments on a large Technical Debt are about to drive the system into Technical Bankruptcy. At this point, the business has to do something to cut the payments: either let it fail and start again, or spend some real money making it better. True, many organisations appear to choose a technical loan shark to help them out, probably the same ones who got them into the mess, but it doesn’t have to be that way. A “good” rewrite is a chance to revisit a chunk of functionality that has been proven useful and is now better understood. That’s partly why Alan Kay talked about “burning the diskpacks”:http://c2.com/cgi/wiki?BurnTheDiskpacks.

OK, so I can hope…