I stumbled upon an interview from JAOO 2007 with Joe Armstrong and Mads Torgensen discussing Erlang, concurrency and program structure (objects versus interrelated processes). It was really interesting to see how similar yet different their points of view were. I’m not going to paraphrase, as it’s worth listening in on it.
Two points came out the conversation that are worth talking about – the fallacy of the silver bullet language, and the right tools for the future.
The premise of The Church of the One True Language goes something like this: “you can do anything in my language”. Write servers, build databases, write accounting apps etc. But if you think of languages having their sweet spots and use cases, much like libraries, that pretty much falls apart. I for one, wouldn’t want to be writing hugely parallel software in Java, just like I wouldn’t be writing web services in Erlang. Sure it’s doable, but probably not the best way to go about it. So it makes sense, that unless you want to be working in the one problem domain for the duration of your career it pays to diversify. Right tool for the job and all that.
This leads me to something that I have been thinking about for a while. The multi-core era is upon us, and we don’t have the right tools for the job.
OO programming makes it easy to design by component, and organise and compose the pieces to desired effect. The problem is that those same concepts break down when you think of system-level services like threads, and the interaction of your pieces with the platform. Should a thread really be an object that can be controlled by the programmer? I think probably not.
Writing multi-threaded software is really hard. After reading Java Concurrency In Practice, I realised the nuances of just how hard it really is, and how easy it is to do the wrong thing. Even really smart people get it wrong. The core of the problem is shared mutable state, and any language that does not sufficiently separate the effects among threads can, and probably will, end up doing the wrong thing. Erlang’s message passing model is quite cool in that it separates processes, yet it falls over on the front of modelling entities and the relationships between them. Not surprising given its design philosophy.
This seems to be the crux of the problem – the next generation of apps will have to deal easily with breaking up problems in an easily concurrent manner, but at the same time model the world in “this object is a bank account that belongs to that guy over there” abstractions that we have become used to thinking in. Those abstractions seem to be at odds with each other using current development paradigms. You can stick Actor libraries on existing languages, but they still don’t make it impossible to mess things up. This is ultimately what the next-gen programming environment needs to address. It should be really difficult to mess things up. Threading should be as though of like garbage collection in a modern VM (i.e. you should know how it works in case things go wrong, but can pretty much depend on it to work correctly the rest of the time).
Maybe the correct approach isn’t to duct tape these concepts together in one syntax, but rather to have different abstraction in a language that model each world-view seperately. This would be a bit like using floor plans in combination with elevations in building design. Or, for that matter, class and sequence diagrams in UML. Both represent a facet of the whole, but neither is fully complete on it’s own.
Either way, it pays to diversify. Languages have their own particular sweet spots, and problems that they address well. Even if we do manage to marry an object view of the world with transparent multi-threading, that willl just highlight a different class of problems that cannot be easily solved using that approach.