Thursday at the Summit
By John.Rose-Oracle on Sep 17, 2009
It's been wonderful so far, and I'm looking forward to the final day tomorrow. You can see what we've been talking about by clicking on the talk links in the agenda; most of the slide decks are uploaded there. Yesterday I was personally inspired to see how Charlie Nutter and Attila Szegedi are experimenting with invokedynamic and the rest of JSR 292. Later in the day we had a workshop on JSR 292, in which actual and potential customers and implementors of invokedynamic gave high-volume, high-quality comments on the remaining design questions (see the proceedings wiki for some). I also enjoyed David Pollak's presentation on the internals of Scala, a language I dream of retiring to when I'm done coding VMs in C++.
Many of the talks are encouraging us to "think different" about the problems of organizing complex software systems on managed runtimes on gigantic machines. Two big contributions to this quest today were Erik Meijer's talk on his non-blocking "reactive" framework, and Rich Hickey's keynote. Rich (like Erik last year) encouraged us to rethink how we use memory and data structures, and particularly get much tighter control over mutability in our data structures.
On another personal note, I was delighted to see the use Rich made of classical philosophy in the writings of Alfred North Whitehead. On about slide 16 I was struck by the observation that "all things flow". You see, on Monday I was teaching Plato's Theaetetus to a classroom full of bright high schoolers (including my son Bob), in the course of which I had written on the board "all things flow" (παντα ρει, specifically), as an early problem with which Socrates and his successors struggled. I like the great books, and I like software engineering, and so it's a real treat when they synergize!
The problem of "flow" or "flux" was vigorously posed 2500 years ago by Heraclitus, who liked to speak in riddles about rivers and flow and The Word and The Way. The problem is that, if you can't step into the same river twice, the identity of the river itself dissolves into a series of isolated events or perceptions. Rich's observation is this old problem nicely describes some of the root problems of the object-oriented model: You can try to make an object have a stable identity over time, but as you allow state transitions to pile up with little structure, you begin to risk its integrity (or the integrity of your use of it).
So the next ancient "paradigm" to flux was stability. Parmenides and others (like the famous Zeno of the motion paradoxes) said that change is not real (a tragic maya-illusion for us commoners) but that real reality must be eternal and stable. Plato inclined towards this position too, hence the proverbial "platonic world" of ideas; he accepted the world of change as a poor imitation of the pure eternal world.
There in fact is a similar "paradigm 2.0" for software systems: Pure functional programming tries to remove the embarrassing problem of flux by working in a timeless, stateless reality of immutable values. Want to set element #59 of an array? No problem, but first you have to build, beg, or borrow a copy of the whole array, one which has "always had" the desired value at #59. It's hard to get the hardware people to build us memory that can do that in one step, like our old fluxy "set and forget" arrays.
But we know from common sense (that trusty yet abused helper) that we live somewhere between the fluxy world of Heraclitus and the timeless world of Parmenides. In the days of Plato, it was his student Aristotle who balanced the claims of the two accounts, picking a middle way between the two. In short, the formal ideas we perceive and know inhere (in a way real though bound) in the mutable, moving reality around us. Object identities (what he called "substances") are real, though temporal. If Aristotle had marketers like we do, he might have called his account a hybrid paradigm (more Greek, actually, though to him "hybrid" would mean "having hubris") of flux and form. I think it's likely the story will end similarly for us, in our professional difficulties with software, with some sort of middle way.
Just to speculate wildly, maybe those hybrid functional-and-object-oriented languages (like Scala and F#) can provide a sort of dictionary and grammar of useful terms and constructs. These would somehow describe computations as immutable in most places, and manageably mutable in those few aspects needed to model real-world transitions. (Or to implement localized compute engines, like a quick-sorter.) Compared to Scala and F#, Rich's Clojure language and data structures provide a more explicitly limited set of patterns for managing flux in programming. It's growing to be familiar story these days... but today the connection to my dead old Greek friends was very fresh to me. I never before dreamed of a connection between Heraclitus and Smalltalk, or Haskell and Zeno. Thanks, Rich!
A final note, firmly back in the 21st century: The hardware people continue to build us faster and bigger Von Neumann machines, with a fiction of globally knowable, infinitely mutable memory. It's a combination of flux and stability: The memory cells are notoriously fluxy (more each year as new processors are piled into the designs), but their addressing scheme is changeless. It's an odd model, since in reality modern memory systems are extremely busy changing the addresses under our noses (that's what caches do) and running highly complex network protocols (totally invisible to us software folks) to keep up the fiction of a fixed global sequence of cells. The changeless addressing scheme makes it hard to talk about sharing and unsharing chunks of data, as they flow (that word again!) from processor to processor. On the other hand, the radical changeableness of each and every memory cell (by any processor in the global world) makes every load from memory at least slightly uncertain. Some of worst failures we call "pointer stomps", and they amount to dipping into the same river twice and getting toxic waste the second time. For most of our data structures, most of the time, the radical mutability of their component memory cells is a potential liability. Because their cells are located in a single place in the global memory order, it is often difficult to send them to all the places they are needed. As I said earlier today, maybe the problem with today's global, mutable memory systems is that they are global and mutable. What might a mostly-immutable, mostly-local memory system look like?