The Ruby language has this great feature called Mixins. It lets you add methods to existing classes. Take this example from Ruby on Rails (which uses mixins heavily):
time = 2.days.ago
Yes, that’s valid code and does what you think. The result is a DateTime object. It was accomplished by adding methods the Numeric and to DateTime. If you come from a strongly locked down language background, this sort of thing horrifies you. If you don’t, you think it’s awesome. Remember, this isn’t inheritance, it’s actually changing the fundamental classes. This makes it much easier to retrofit on existing code. The python folks call it Monkey Patching, which makes it sounds kind of dirty. I like Mixins better.
While Ruby has been my language of choice for personal time hacking, I’m doing a lot of Java recently due to working on Android things. This past weekend I remembered one of the things I dislike about strongly typed languages: type gymnastics.
If you’ve got a time as milliseconds in Java and you want it in a string you’ve got to first convert it to a Calendar, then to a Date, then give that Date to a DateFormat. You’d think that Calendar.toString() might actually give you something useful, but it doesn’t. Oh, and also realize that every one of these objects has it’s own internal notion of TimeZone, quietly gotten from the system, so if you are trying to do something in UTC, you have to manually force that on them all. This is the crux of type gymnatics, long changes of type conversion operations because to get from A to B (in my case A:long, B:string) you’ve got to go through C, D, and E in the right order. These conversions are error prone, and clumsy, and largely produce some part of your namespace called “util” that is largely static methods to convert between one thing and another.
This is because the authors of A never thought you’d have to get to B. What’s so interesting about B? C is really nice this time of year, wouldn’t you just like to stay there instead?
The real problem is that original authors of software rarely really understand what their software will be used for, and the more immutable languages don’t let you fix things after the fact. In Java this means that any project ends up with a “utils” package which is used to do conversions between types that can’t natively be converted. All that code is just boring boiler plate, which is where you are most often going to make a hard to find mistake. Nothing generates errors like boredom.