Archive for November 2008

The Hugeness

Most of what I’m going to ramble about here was covered much more eloquently and in far greater depth in Beyond Java. These are my personal feelings and anecdotes on Java and it’s history. I should also note that despite what appears to be a moderately negative tone, I still do use Java extensively and used it to build the product of the rather short lived startup I co-founded.

I first encountered Java way back in 1998. This was effectively my first programming language, though I had done some C++ in high school. That wasn’t formally, mostly self taught and pretty much purely due to laziness. At one of the computer shows in Vancouver, (which might have been Comdex, did that show travel around?) I talked my father into buying me a C++ compiler and toolchain. It was definitely Borland, I’m fairly certain it was one of the Turbo C++ packages, though I have no idea which version now. Regardless, my main goals were to ease my physics and math homework by writing programs to do various tedious calculations for me. That was more or less a success, I still recall the joy at punching 3 numbers in and getting the solutions to the quadratic equation back. I learned about loops, variables and if statements, but nothing else really. But I digress.

At Carleton University, the first programming course I took was in Java, at this point in time, we’re talking Java 1.1 for the most part, the entire API was a couple of hundred classes at most. Supposedly it was kind of exciting because it was object oriented, but that was way beyond me for at least a semester. Mostly what I recall from my entrance to the world of programming was my epic battles with the compiler. I hated javac. There was perfectly valid… things in my file, at least as far I could tell, but javac would tell me that in no uncertain terms that I could not go so far as to call that text ‘code’. Eventually, the program compiled and joy was felt throughout the lands. Immediately thereafter, I would run the program, which would crash with a NullPointerException or some other fun error case. This was before the time of decent debuggers, at least to a novice programmer, so with a liberal smattering of System.out.printlns, eventually I could figure out where I had a mistake. Then change the code, fight with the compiler and the scenario would repeat itself until I could run the test cases provided in the assignment.

All in all, though, Java in those early days was a pretty simple language. You would make an array, do stuff with it and be happy about it. Or, once you started to grok how this object oriented stuff worked, you’d make a Vector and stuff things inside of it and you would never worry about resizing the array again. I mean, there wasn’t much to the language, check out the 1.1.1 API I just googled for. There were a couple of weird features for a novice to see, anonymous inner classes are a great example, it took me years to really understand how to effectively use those things.

Java 1.2 was introduced in December of my first year and included a number of things, the only ones that actually mattered to me as a fledgling programmer was Swing and the Collections library. Swing because the winter term had a Java graphical user interface (GUI) course and the collections library because I could now cheat and use LinkedList instead of always having to write my own for each assignment. Maybe it wasn’t every assignment, it just seemed that way, still.

Java 1.3 did not really add anything of use to me and stayed out of my awareness. Java 1.4 added a few more things and I wrote a fair bit of code with that version. Still though, Java was still the same old Java as I had used back when I started with it. There were new libraries, and that was nice, Java was growing with me as I needed to do more with it. There wasn’t any real new syntax that had to be learned, if you hadn’t seen regular expressions before, it was a bit of a shock to see Perlish things in Java 1.4 but for those of us who had used them, it was nice to have the power of regular expressions in Java.

By this time I was working in the industry, specifically on a rather interesting Java application that was officially using 1.3 Java when I first showed up on the scene, 1.4 shortly after I started writing code for it. I should  note that I mean interesting in terms of the curse, “May you live in interesting times”. Not as in, “That book is great, some really interesting points.” The system was the definitive legacy but business critical application, so arbitrarily going to a new Java version wasn’t going to happen until the powers that be had given it the official green light. At the time I was happily drinking the generics kool-aid, helped in no small part by the .NET team at the company who was gushing about how much the .NET generics implementation had helped them. I pushed for the migration and eventually we had migrated to a 1.5 JVM and all was good.

I learned the new syntax for the generics and for a while it was great, but a few things were beginning to bug me. In the entire time I had worked at this company, I hadn’t actually seen a ClassCastException in the wild. This appeared to be the main thing that the generics were attempting to fix. The syntax was a bit clumsy and fairly verbose, especially if you had descriptive class names. Making a generic class was an exercise in pain. Enough so that after one serious attempt, I nixed it in favour of a single purpose class that could only take instances of a given interface. Most grievous in my mind was that after going through all of this anguish to get a generic class, as soon as you hit run time, you could not use reflection to actually figure out what *should* be in the container. I remember being shocked when I found this out and needing a coffee break to reassess.

From what I could tell, all of this extra syntax was being entirely tossed out before run time, which meant all that extra typing and ‘safety’ was a merely a compile time check. One of the first lessons learned in programming was that just because something compiles does not mean it works. So while getting a bit of extra information at compile time is nice, I couldn’t help but think the benefits of the check was not worth the cost of the extra time spent typing and managing the syntax. (Side note, no, it’s not ‘just typing’, it is the most fundamental skill a programmer needs to have and should be taken very seriously. Arguments here and here.)

Regardless, I soldiered on and slowly encountered other 1.5 enhancements that made Java more complex. Annotations, which through a new syntax would allow you to add some extra meaning to a method, class or variable. Enumerations, which I do love using when the previous option was lists of static final integers or strings. That however, was done with a new keyword, ‘enum’, which by some entertaining coincidence was the exact variable name used throughout our codebase for Enumerations. (Enumeration enum = hash.keys(); Eventually I will write more on code quality in that entertaining project.) Never mind the fact that now you have to talk about Enumerations or enumerations, which is always entertaining. Then there is the varargs syntax, which just feels like a solution in search of a very specific problem. Seriously, I mean, have you ever needed this? Then there is autoboxing, a nice feature, but blurs the lines between objects and the Java primitive types, which can lead to a whole new way for developers to misunderstand what a block of code is doing.

I no longer feel that Java is a good language for a new developer to start programming in. It has it’s advantages, but those are almost exclusively in the domain of large ‘enterprise’ systems now. Some of the changes appear to have been to keep maintenance costs down and to mitigate the damage a low quality programmer can do. Some of the changes appear to have been good ideas, but they were done at the cost of making the syntax more complex and complexity is the enemy of software development.

Snowtastic

Cyclocross is a sport of bad weather. Cold winds, rain and the threat of snow is taken in stride and often times, the weather plays an important role in a race. The second race at the Kanata Rec center was one of those. The temperature was hovering around the freezing mark with 30km/h+ winds and some light sleet. Or perhaps you could call it heavy snow, it really doesn’t matter.

This was the first race at the Kanata course where we were not sent up the gravel climb up the side of the main hill (according to my GPS, that climb hits about 14% at parts). Instead, the main elevation gain was up the other side of the hill and running. Even more entertaining was the fact that immediately after the run up, a pair of muddy switchbacks were presented. After scoping out the route through the switchbacks, I ended up electing to not remount the bike until I was through the first two. Most people tried to ride, but I found that running would tend to move me up a place. Considering I am an absolutely terrible runner, this was saying something. I also did not fall, which was nice. Some say that in cyclocross, if you don’t fall, you are not trying hard enough. I do not subscribe to that point of view yet. I much prefer to keep the rubber down for the time being, I don’t bounce as well as I used to.

Personally, it wasn’t my greatest race. I slogged through it, but it was far from stellar. I got lapped by the top three guys and that was about it. Second best result this year I suppose, though it was a longer lap, so perhaps not. I evidently just wasn’t with it mentally. I’d hit the long into the wind power sections and just wasn’t able to dial it up as high as I usually can. Ah well, they can’t all be good races.

I most likely will not be attending the Upper Canada Village race next week, which means one more to go this season. Too short it is, but the weather is just getting more and more unpleasant.

A code post is in the works, this week’s topic is going to be a ramble on how I feel about how Java has changed since I started using it in 1998.

The Lead Lap

In the world of amateur cyclocross, at least in the series I participate in, there is a certain progression you follow, assuming you aren’t a seriously fast dude who just needs to learn to ride on the grass, sand, mud, snow, gravel, stairs and well, you get the picture. I am not a fast dude, so I will not attempt to relate the shock and horror that they feel when they first try out a cyclocross race. If you want that kind of perspective, try this. That’s not me. I’m going to talk about what happens when you start racing ‘cross as a normal human who likes riding bikes.

The first race is a rude awakening. It hurts, in ways that cycling has never hurt before. You get lapped by guys who fly over the bumps in ways that appear to defy physics. You get lapped by the top riders, as does at least half of the field, but if it goes well enough, you come back next week for more.

The being lapped become a regular occurance. In my local series, we have actually had the national champion show up for a couple of races. However, sooner or later, as the skills improve and the speeds go up, eventually something odd happens. The fast guys don’t come around you. This is not always as nice as it sounds. As has often been quoted by famous cyclists, “It doesn’t hurt less, you just get faster”. What this means is, rather than being able to stop a lap early after the eventual winner has finished, you get the honour of doing the same distance as them. You get to suffer longer.

That has only happened to me a couple of times and in general in the races with longer laps where you just don’t get lapped as often. I didn’t get lapped today.

The race, the second one of the year in Almonte was a mud pit. After I had finished, I had mud caked at least 3 inches up each of the spokes, to say nothing of the incredible amount of grass and mud that had made it’s way into every nook and cranny of the bike. I easily carried an extra 2-3lbs of mud around by the end of the race. That made things much more fun, believe me. On the plus side, they did not put the bottom part of the park into the race, so the climbs were not as long or quite as sharp, which was nice. The mud made up for it though. I found that for large parts of the course, I couldn’t actually go at full power without crashing or just spinning my rear tire.

With a major race happening in Toronto this weekend, most of the top guys were not around for our little grassroots race. That said, there were at least a couple of riders who lapped me in Kanata the week before, so it was still going to be quick. It was. With far fewer riders this week, things got lonely fairly quickly. I spent most of the race falling behind the guy in front of me and pulling away from the guys behind, not much in the way of tactics, it was just technical and ride as hard as you can.

The last third or so of each lap was mostly on a series of fields, so you can see around you and who is coming up behind (or ahead). With 2 laps to go, officially anyhow, I could see someone coming up who was definitely not the guy who I’d had behind me all race. “Oh well, here comes the lap.” At the same time, I was also thinking that this was pretty close to the end of the lap, I might actually survive. I was somewhat torn. I could slow the pace and end my suffering, or I could continue to go as hard as I could and hopefully stay ahead.

In the end, I couldn’t slow down. I held the pace and while the eventual winner of the race was closing as if I was standing still, I managed to punch it and cross the finish line before him. For my efforts, I earned the privilege of doing another lap.

All in all, I ended up ahead of a few of the guys who had beaten me in Kanata, I finished on the lead lap on the most technical race of the season thus far and managed to dig deep and stay ahead of the winner. I should note that in no WAY am I saying that it was a close race between him and me. In the final minutes of his race, he probably closed 100m+ on me, it just so happened the the convergence would have happened several meters past the finish line.

Don’t matter though. I’ll take it.