Each language feature introduced that tries to enforce safety of some kind invariably introduces some reduction in the power of the language. Some of these tradeoffs’ seem acceptable. The Java security model is an example of a limiting factor in the deployment and execution of a Java application which makes perfect sense to me. Java also hides memory management and pointers from you, which for the majority of applications also makes sense, however sometimes you really want to get hold of the underlying memory model and do nasty things with pointers and that is why C and C++ are still used for writing OS API’s.
Other limitations just become more frustrating over time. Java’s strongly typed language provides a great deal of compile-time checking, at the cost of program flexibility – Python, Ruby et al provide a richer, dynamically typed language which gives the programmer much more power (And anyone saying “You get dynamic typing with Groovy” is going to get smote with the cluestick of death, +1.). At this point I’d like to borrow a phrase from Spiderman (uh oh – nerd alert!) “With power comes responsibility”. Such dynamic languages with their more flexible typing can also get you into a bit of a mess. These dynamic languages can be seen primarily as enabling languages – they make the assumption that developer actually know what they are doing. As a result, they will on occasion let them shoot yourself in the foot. C and C++ likewise let you shoot yourself in the foot – they also however let you shoot the guy next to you, blow your car up, drink your beer and steal your girlfriend, but that perhaps is a discussion for another day.
With Java, Sun used the typing model to provide the developer with some safety by enabling complie-time checking. They attempted to enforce good OO practises by not allowing multiple inheritance of base classes. I can only assume they tried to keep things simpler by not introducing generics sooner. However each of these things can become a frustrating limitation in the hands of a developer how knows perfectly well that you shouldn’t point the gun at your foot, play golf in a lightning storm or eat yellow snow. Perhaps it is time the Sun started to accept that some of us actually want that power?
When I was thinking about this, I started to think about the relative merits of several languages, and mentally started to plot them on a graph (well, actually I started out to make a league table, but in the end that didn’t make a whole lot of sense). Along the X-axis we have power. Along the Y axis we have danger – or, the number of ways in which said language can really ruin your day. The realisation I can to quite quickly was that the relationship between the power and danger associated with a language is not linear – I consider C and C++ (I have amused you are using ‘safe’ C# code) to be more dangerous than the dynamic languages of Ruby and Python and yet not as powerful.
It’s important to note that the relative strengths and weaknesses of these languages can be contextual – for example Haskell makes it extremely easy to do some very complex jobs, but some other simple tasks can be a real pain to perform compared to other languages (IO comes to mind). Please also note that I’m talking about the relative powers of _language_ features – excluded are factors such as the ease of installation, performance, rich API’s etc. Such comparison can wait for another day.
The relative plottings on the graph are purely subjective and are based on my own (in some cases limited) experiences with the languages in question – a more quantitive study would no doubt yield more interesting results, but such a study would in all likelihood get in the way of me making sweeping generalisations. Flame away!
_Update_: Some problems with the graph display, should be sorted now.