Monday, January 22, 2007

A Favor

Pat Maddox wrote a post called "Java People Must Be Stupid," and unfortunately, his irony blew up in his face. The point of his post isn't really that Java people are stupid -- it's that Java people coming to Ruby often seem to arrive with the crippling assumption that their fellow programmers are stupid.

What worries Java immigrants to Ruby is that Ruby doesn't have any of the protection mechanisms Java has, and the protection mechanisms it does have are easily circumvented. Pat's point is basically, "let it go, don't be afraid," but his phrasing put him right in the middle of a language war.

Anyway, I posted a comment there, and Reg Braithwaite asked me to post it on my own blog, so he could link to it without including all the shrapnel and debris from the language war, so here we go:

It’s not really stupid people, it’s people who’ve accepted a stupid idea. Java’s design is based on the idea that a language can prevent misuse by making bad things hard to do. It’s defensive thinking. Java people are caught up in this paradigm; that’s where these questions come from.

It might be more accurate to say that Java people are smarter than they give themselves credit for.

The thing is, telling people they’re stupid, when their problem is an equal mix of bad ideas and defensive thinking, that’s not the most persuasive argument available.

I think the only compelling argument, from a Java perspective, at least, in terms of Java people I’ve talked to, is that nobody ever actually accesses the stuff inside Rails which, if it were inside Java, would be hidden. The door isn’t locked, but still nobody goes in.

In any OOP language you do want to keep client programmers only using the API, not the internals of the objects the API is made of. That’s a good design principle. Java makes it happen by building a fort, locking everything down, the theory being they can’t steal it if it’s nailed to the floor. Their goal is legitimate, but their way of achieving it is kind of paranoid. Ruby’s got the same goal, but a radically different approach to achieving it. It doesn’t enforce any kind of security, but makes it easy to build such elegant APIs that entering the “forbidden zone” never even occurs to people, because it just isn’t necessary.

It’s like the opposite of thinking defensively isn’t thinking offensively; the opposite of thinking defensively is thinking creatively.

I've been writing Java code since 1999, and while I like that the compiler will tell me when my code is provably wrong, I don't like having to give it information to achieve that.

That's why I think the Haskell type system is superior, although it is certainly harder to get to grips with. I haven't got completely comfortable with it yet, perhaps my opinion will change. I might need a strict imperative language with type inference.

Having programmed in Java for so long, I've refined how I write it. I keep interfaces small, one method where possible, preferring static methods that operate on minimal objects, over instance methods.

Scala's mixins would allow me to treat those statics as instance methods without changing the object's code, which is good.

I don't care much for private methods/fields - rather than use private I make anonymous implementations of interfaces.

One of the ideas of defensive programming is that you can defend against yourself; you're not assuming that you are an idiot, but that you will approach the code without the context that you had while writing it.

In that situation, extra (visible) methods on objects are just noise, obscuring the signal. In the Java APIs, JButton is a good example; it has many many methods, most of which are just implementation details inherited from superclasses.

It is possible to write defensive code creatively; a little Haskell use persuades me of that.

It's all about the developer experience though. Ruby seems attractive because it gets out of your way and lets you code (I don't know this, I'm just assuming that it's in the same arena as Lisp).

"It doesn’t enforce any kind of security, but makes it easy to build such elegant APIs that entering the “forbidden zone” never even occurs to people, because it just isn’t necessary."

Errr... I guess you don't work in the finance industry then. What you say is fine in many situations, what what if need that security/protection against misuse?

In an everyday situation, it is often more important to be able to demonstrate from a compliance POV that your code takes appropriate steps to prevent misuse, than there being much risk of it.

I don't want to plug some 3rd party API into my financial applications (like an API from a bank), which could possibly route through my code and send them back the trading algorithms I use. I want to lock down what they can do, which is easy enough in Java though isolation, tightly-written API's and the SecurityManager mechanism.

I guess this is a reason why Java would live on in the finance world...

I love Linux. However, it is a shame that some people in the community put a cushion around their ears when a feature is needed they they don't use, and then try to generalise about it. Just because they don't use it, doesn't mean it is absolutely vital for enterprise development.