According to AlanKay :
We need to do more building of important software structures, and we need to do it in a form that allows analysis, learning, and reformulating the design and fabrication from what has just been learned.
There seems to be a bit of a chicken and egg problem here. If we don't really have an engineering discipline, then won't it be too difficult to make big constructions that are also understandable enough to learn from? And won't the mess we've made be too difficult to reformulate to give us a chance to understand whether our new findings really have value?
I believe that the secret weapon that can be used to make progress here is extreme late binding. Of what? Of as many things in our development system as possible.
One can make a good argument that most of the advances in both hardware and software design have been facilitated by introducing new late binding mechanisms. Going way back in hardware, we can think of index and relocation registers, memory management units, etc. In software, we went from absolute instruction locations and formats, to symbolic assemblers, to subroutines, to relocatable code, to hardware independent data structure formats, to garbage collection, to the many late binding advantages of objects, including classes and instances, message sending, encapsulation, polymorphism, and meta-programming.
Human late binding
: Basically LateBinding is a wonderful thing ... when the computer does it. But the Squeak interface wants the benefit of late-binding your hardware to an abstract interface model, where the user has to remember the transformation between the two.
OTOH Wiki's ConcretePageNames are an interesting case. They're concrete, so the page-names are statically bound to the contents of the pages. (And that's OK, because names are connected with page contents by the semantics of your natural, human language). But at the same time you can make a link to a page which may or may not exist. And this will only matter at browse-time. That smells pretty late.
More things bound late == more flexible software. The key to sophisticated software systems is move beyond imperative, structured programming. And this involves introducing a new kind of late binding : the binding of names of actions to blocks of code at run-time.
This comes in two flavours : FunctionalProgramming and ObjectOrientedProgramming. In FP, functions are first class citizens, so one function can receive another as an argument. In OO, late binding occurs through polymorphism : when I pass message m to object o as in o.m() which block of code m is bound too depends on the class of o at the moment the line is executed.
Both FP and OO are fundamentally ways of getting late binding of names to blocks of code. However, they are different the way poetry and prose are different. You can use either to tell a profound truth about the world but your strategy is different.
Prose works with more or less ordinary language. To tell a profound story, you must skilfully organize a lot of it, carefully modelling the truths you wish to capture. The structure of your story is everything. Plotlines and characters must ring true. The dramatic arcs must create the right flow. Counterpoints must be balanced.
Poetry is different, you do not expect to write many words, nor are you necessarily troubled by large scale structure, but you must make every line do more work. Your lines will not be ordinary but will have a special exoticism : they must be multiply overloaded with meaning. (FractalLoading?)
OO is, of course, prose. The lines look and act more or less like the familiar lines of C or Pascal. Modelling and structure are everything. Late binding of names to blocks of code occurs, of course. But is rigorously constricted and well organized. FP is poetry. The lines look weird. Like poetry it's all about ambiguity. The ambiguity of things whose shape is not fixed but radically reconfigured at runtime.
“Late-binding” is an idea about having desired functionality while retaining as much flexibility and safety as possible.
A big one to consider is that “software” itself is a late-binding of how a computer will behave. (Seems to be a pretty good idea, I’d say …)
At the next level, the idea of index registers in hardware late-binds addresses in a way that is not destructive of code. Memory management units (MMUs) allow global relocations with encapsulated local addressing. Indirections of various kinds allow easier changes at run-time.
Consider a variable …
Consider a subroutine compared to in-line code …
An interpreter late-binds semantics of a computer.
Consider microcode as a way to later bind the hardware via an interpreter
An encapsulated object late-binds the “hows” (methods) and allows usage just via “whats” (meanings), and this allows various kinds of alternatives and transparencies to be more easily accomplished.
The “hows” themselves can also be late-bound e.g in Lisp or Smalltalk this allows programs to analyze how other parts of the system are set up: to “reflect” on what and how things are done.
(“Reflection” done well, and allow more pragmatic possibilities, even at a very low level, to be carried out safely and efficiently. A good book — mentioned in a comment below — is “The Art of the Meta-Object Protocol” by Kiscales, Bobrow, Rivera …)
From a strategic standpoint, retaining as much late-binding as possible is a very good idea. It is much easier to dynamically remove some of the degrees of freedom if absolutely needed, but really difficult to go the other way round from an early-bound system to more flexibility.
For example, quite a bit of optimization is violating module boundaries and hoping to get away with it. One way to do this in a more principled manner is to really have late bound modules as a model, and then implement the violations as “pragmatic features” of the programming system.
For example, a method in an OOP system could have a “left-hand side” that is just semantics, and an optional “right hand side” of cases with optimizations. The method should run perfectly with the right hand side turned off, but will run faster etc with it turned on.
Similarly, interactions between modules can also be handled in this dual way. (For example, Smalltalk is a “message passing system” but did not manifest actual messages unless absolutely required. Also, Smalltalk had simulations of all of its semantics and could retreat to them if the lower levels on some machines were not complete or had bugs.
It’s worth noting that deep enemies of graceful and useful late-bindings are pernicious — and especially gratuitous — dependencies. These can happen in an early bound system, but there are more possibilities in a late-bound one (so much more design is required to really take advantage of the idea — this will pay off in many ways …).
See also : BradCox's ideas static and dynamic binding outlined in this video : http://programming.nu/posts/2008/03/21/announcing-nu
Backlinks (24 items)