Tuesday, November 8, 2011

Buridan's Ass and the decline of Object Orientation


For those of working as programmers today one of the main questions is which languages are likely to retain their current traction going forwards?  Looking at the dominant mainstream languages as candidates I think even in the near-mid term the answer will be "none of the above". 

This leaves us in somewhat of a dilemma; Karl Popper in his classic essay The Poverty of Historicism points out that "It is logically impossible to know the future course of history when that course depends in part on the future growth of scientific knowledge (which is unknowable in advance)", and further, even if we did have all the information in advance we cannot even solve a three-body problem, let alone try and account for the myriad of variables present in the general computing ecosystem.

However, to stop us turning into Buridan's ass we must put aside Poincare and Popper's observations on the unknowable and non-deterministic future for the moment and take a view on this. We necessarily cannot become experts in all languages (and still have a life) and there must focus on a likely subset. 

It is useful here to take a quick look at the current environment. Like many of you I expect, my professional programming since the 90s has split between C earlier on, moving to Java or a similar VM-based language and client/server scripting languages, with occasional forays into less mainstream languages. In the wider world Groovy, Scala and Clojure that build on the independence of virtual machines are gaining some following, and there has also been a re-emergence of languages from the 90s such as Python and Ruby, and that child of the 80s, Apple's creaky Objective-C as MacOS and IOS have picked up substantial mindshare. 

Which brings us to approximately now. While Popper's point is that something novel may well spring up that we could not anticipate we can still make some guesses based on what is happening around us. There are at least 2 pygmy elephants in the room that are rapidly growing, namely, on the hardware side the move to multi-core computers and in the application domain the rise in always connected push-type applications for tens of thousands if not millions of simultaneous users. These forces are already affecting current development projects and they both contrive to push languages and platforms down the same path, which is horizontal scaling of processing and communications. 

The current JVM-based languages I think are already starting to struggle in this environment and this will only, I believe, become more obvious with time.  The JVM just was not designed with this type of multi-core hardware in mind. The threading model is heavyweight and does not scale that well, the GC is not suited to very large heaps and large numbers of threads and the Java language itself is tied into the concept of shared memory between threads, which makes parallelisation at any scale challenging. While companies like Azul have shown it is possible to progress in the GC area, I cannot see how the other issues can easily be overcome without a lot of re-engineering, which is tricky in a 10+ year old runtime.

It also appears obvious that the newer JVM/CLR-languages and actor frameworks, while offering some possibilities at the language level, are still inherently bounded by the behaviour of the VM itself. 

If we accept this to be the current state of things, we have to look for answers outside the JVM/CLR platforms and also most of the existing mainstream compiled languages. C++ and C for example have no cross-platform standard threading library and the ones that exists such as Pthreads, Win32 threads, OpenMP, and Boost have slightly different semantics, making portability awkward. Python (even the stackless kind) and Ruby both suffer from the Global Interpreter Lock bottleneck which pretty much is a blocker for multi-core scaling. 

Of the remaining candidates, the two most promising appear to be Erlang and Go (Golang).  Without going into too much detail, both heavily emphasise message passing as a primary construct of the language, both are designed explicitly for upwards of thousands of lightweight processes, and both are heavily focussed on the communication domain. Erlang by dint of its telecomm hardware background and Go as a system language designed with excellent communication protocol support in the core language.

Having used both of these languages, each has a few drawbacks. Erlang's syntax takes a bit of getting used to and, not wishing to offend the functional-only crowd,  the purely functional approach will, I think, ultimately limit its appeal. The addition of a built-in non-functional distributed table storage and the in-memory Mnesia DB is a tacit concession that sometimes you need a bit more flexibility than pure functional programming can offer. 

Golang is still very immature and the first official release G1 has not yet made it out of the blocks. The dropping of OO concepts is a big win in reducing code volume (even Alan Kay noted that messaging was the key takeaway from Smalltalk not Objects), the syntax is easy to pick up and the idioms are very terse from a programmer's perspective. However, the language is compiled and does not offer some of the flexibility you can get from VM-based environments.

On balance Go for me has the edge, even with the coarseness of things like its primitive GC and compiler (as these can only get better with time). 

Programmers who have grown up with Java and .Net should keep in mind that the dominance of Object-Oriented languages is probably going to be a thing of the past. Concurrency of scale is the key challenge in the next few years and the languages best suited to this are from a different pedigree. For those of you stuck in that OO-mindset, you might want to start delving into non-mainstream programming styles before you find yourself going the way of the BCPL programmer. 





Thursday, November 3, 2011

Heretics, Development and the One True Authority.

At the risk of playing up to my own golden age bias there is a worrying trend in modern developers to be a card-carrying member of a particular world view based one a "One True Authority" to provide a simple and easy answer to all their problems.

It is not difficult spot the members of the currently popular sects. Every conversation about a development or design issue is a lesson in scripture from the holy text and no actual detailed thought has to be given to the problem as the good book gives us an easy take away answer.  Among the obvious are the uptight Fowlerites clutching their holy domain models, the process obsessed Agileans and their inquisition offshoots, Church of the Latter day Requirement Gatherers and the GOFian and Patternism branches with their platonic one-size fits all models undistorted by the cave wall of reality.

I am not saying that the many books written in these areas have no useful lessons to give us, rather my point is that there is a trend towards the single world "Argument From Authority" bias among a lot of developers I interact with whose views are dominated by these types of computer writings. Argument from authority is a variation of the induction round-tripping problem that leads to "The Authority" being accepted as a source of ex-cathedra knowledge.  Once this is your starting point, then all such pronouncements must be followed in some semi-automaton manner and are the base from which all your opinions flow without critical evaluation. Now, I think if you talked to the guys who actually wrote the books many would be the first to assert this not how they intended them to be interpreted. However, like all reasonable ideas that are not empirically grounded (and some that are) they are rapidly dogmatized by the faithful.

It is as if the actual business of writing programs that are elegant, efficient, performant and based on empirically demonstrable algorithms and data structures is no longer of importance in the higher level world of the true-believers.

The interesting commonality of these types of books and their die-hard followers is that they are only passingly interested in the nuts and bolts of running programs, but rather focus on the process surrounding programming, metrics of the project or vague over-arching non-falsifiable approaches that purport to smooth away the ugly realities of real-world issues.  At the danger of over-generalising, in my experience, many programs that are generated from these divine principles in practice end up bloated, over-complex, poorly designed in respect of their runtime behaviour and survive mostly by the dint of throwing memory and hardware at them. Such ideology cannot make make your programs better if you neglect the runtime algorithmic and data structure fundamentals of lower level programming approaches, no matter how much your belief re-assures you these are mere details, or how close you stick to the divine path.

A respite from this modern zealotry can paradoxically be found in earlier readings that revolve around the specific programming literature characterised in works like Kernighan and Ritchie's The C Programming Language, Jon Bentley's Programming Pearls or Knuth's epic The Art of Computer Programming.  Many of these types of books and papers tended to address specific techniques that can be empirically derived and tested and provide a useful growing toolkit that you can dip in and out of.

Observationally, (and I am generalising again) many developers who are rooted in this sort of background tend to be more open to taking bits and pieces of approaches and techniques as appropriate to solve problems and do not demand that anyone diverging from this view should suffer the fate of all heretics,  and, to quote the Life of Brian, "Even... and I want to make this absolutely clear... even if they do say, "Jehovah. "