"Static typing prevents certain kinds of failures. Unfortunately, it also prevents certain kinds of successes." - Ned Batchelder, quoted by Peter Lund
I had one of these surprise successes today. Situation was: how to report progress to the interactive user of a very long running calculation in a remote image. I began by passing the remote calculator a value model:
remoteObject longCalculation: 0 asValue.
The idea was the calculator's inner loop would periodically send #value: to the model with an update of % done:
RemoteObject>>longCalculation: aModel
1 to: 10 do: [:each | aModel value: (each / 10).
(Delay forSeconds: 1) wait. ]
So far so good. But the advantage of extreme late binding came when I changed my mind and decided to use a Block of arbitrary code to report status. Now it happens that Block also responds to #value: and so the client image can report status in a totally different way:
remoteObject longCalculation: [:percent | Transcript show: percent
printString;tab;flush].
Remote server doesn't know wether client is passing in a numeric ValueHolder or a Block -- it takes anything that responds to #value: . It stunned me and my teamates this worked! We're passing a block context in the client image across the ORB to the server, which evaluates it
inside the client. This little block is far simpler than the distributed event-change notification mechanism!
Question: Remote blocks work Distributed Smalltalk. Will they still work in OpenTalk?
(ed: yes)
Anyway it was a nice late surprise. At compile time I thought I wanted a numeric ValueHolder, and later, during debug, I decided to use a block. (while in the debugger, 'natch). Extreme late binding is so liberating Alan Kay makes it part of his definition of OOP
"OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them"
This is the same sort of thing as the various posts I've put up about dynamically updating a server (or for that matter, dynamically updating a client like BottomFeeder). It's the sort of success you'll never have with a static/late bound language. Heck, you likely wouldn't even try it - you would have to kill the remote server, update the type signatures, regenerate the IDL, and update the client. That's going to take time, and the most likely reaction will end up being "why bother". In Smalltalk, you can just go ahead and try it out. The lower cost of experimentation leads to a lower cost of actual implementation - and a much higher level of willingness towards trying things out.