Pat throws down the proverbial gauntlet with Java People Must Be Stupid. It is a couple of bodily fluid references away from being a Hani post. In short, he discounts the need for strong typing in Ruby:
How do I make Ruby safer? It’s a topic that people bring up on the mailing list every once in a while. People shouldn’t be able to open my classes. They need compile time type checking so the app doesn’t blow up. Extending system libraries is bad.
Seriously, browse through ruby-lang for threads where the starter needs Ruby to be more “safe.” A ruby hacker will cheekily ask, “Why do you need static type checking? Are you going to try to regexp match an Animal?” “Well, no, not ME of course, but somebody else might.” I don’t even know who “somebody else” is most of the time. Is it someone on your team? Is it someone from another department? Is it some random guy who downloaded your library?
Concerns like these all seem to boil down to one major theme: The people I work with are stupid.
The more serious issue is when “someone else” refers to someone whose welfare you actually are interested in, or, god forbid, responsible for. If you need to protect someone on your team from code, there are two scenarios in play:
1. The person is stupid
2. The person is naive
Neither issue is really that difficult to handle. The first one has a very simple solution - fire them. You heard me. If you’ve determined that this person truly has no chance of learning how to judiciously use some piece of code, there’s zero chance they’ll had value to your project. Programming is a vigorous intellectual exercise, and I’ve never seen incompetence actually benefit such endeavors.
Ruby doesn’t need to be more safe. It certainly doesn’t need static type checking. What we need is to kick the idiots out, and educate those with less understanding. Doing so improves those individuals, ourselves, and our craft as a whole. It doesn’t take much more effort than trying to keep people from shooting themselves in the foot and performing damage control when they find workarounds. The benefits are obviously way better. So what’s stopping you?
Now. Let me be clear here. Static typing isn’t an end-all-be-all of making your language safe, and certainly not foolproof. But there are some important things to consider here.
1. If you are creating an API for other people to use, typed arguments and returns make your code (closer to) self-documenting.
One of the things that kills me about the Ruby people is more than a few times when someone asks about the types going into and out of API type methods, the answer is “Write a test case.” This strikes me as the apex of lazy on the part of the API developers. You didn’t document it, and the language doesn’t give me good hints, so it is my problem to figure out how the method works by writing tests. Like I want to test someone elses code. Frankly, this kind of thing pervades Ruby as a problem. The JRuby guys are constantly bumping up against the fact that Ruby has no language spec (though the Wikified spec process has recently begun) which means they have to test and replicate every edge-case behavior in the language. You carry this forward into APIs and, idiot or not, you are making more work for other people.
Now, I am a fan of duck-typing. Indeed, support for duck-type adapters in Java is one of the reasons I have wanted Java to have Dynamic Proxy support for concrete objects for so long. I hope that language level property accessors will open up this possibility as the entire front-side of an object will be definable in interface form. However, feed( Duck ) is still easier to figure out than feed( Object ). In a dynamic language, you don’t even have to enforce it, but having it simply expressed — as you can see in ActionScript — helps a lot for people using your code.
2. Extending core classes is a security problem.
When you work in a large enterprise with many teams working on many internal applications and internal APIs that those applications use with a mix of security modes for each of them, opacity is sometimes important. More important, however, is making sure you can’t inject a String that, say, emails passwords to some account, or at runtime clobber the behavior of a policy-managed class. In this case, having ENFORCED typing is actually important. While there are certainly large Ruby apps roaming around out there, I haven’t seen any discussion of multi-team/multi-project groups in an Enterprise dealing with these issues yet. Isolation via WS-* calls is an option there, but sometimes that is less than practical.
3. Static Typing makes large-scale automated refactoring possible.
As a GWT fan, one of the things that people keep looking at Java for is the tooling. While Tor seems to be making great strides in the Ruby support, automated refactoring in untyped languages is hit and miss at best, completely impossible at worst. For my money, good refactoring tools in the hands of the average developer has been one of the great leaps forward in development over the last decade, and it is a big encouragement to have better APIs and internal code. Loss of this is not something I would like to see on a large scale. When you are talking about multi-project-multi team, losing the obvious checks against code that gets a new version of an API is a problem, even if the refactoring works as advertised in the API project. Again, you are back to writing test cases against someone else’s API to see if there are obvious breakages.
All these points aside, I won’t dispute that there are a lot of bad developers out there. I am certainly not going to call Ruby people stupid, but I think there is a mismatch here. I like Ruby, and it obviously has big advantages in certain scopes, but those advantages cost it in other areas. Seeing people advertise it as the end-all-be-all language without admitting the places where it is worse than what we have in other language is a staggering level of arrogance.