An Application Programmers Appeal

My fellow application programmers,

Have you ever noticed how sometimes you learn on the run, slapping together code from working examples, and other times you take your time, really study the technology, savoring it and understanding its complexity? Have you noticed that there are some things which are far more amenable to one than to the other?

What if all learning starts out as "on the run" learning? You pull something into a project to make your life easier, to abstract away something that you don't want to do. You don't want to become an expert. If you can adapt an example its a good sign: you are playing to the libraries strengths, and don't really need to learn much about it for it to be useful. JodaTime might be a good example, or any of the Apache Commons.

Sometimes you pull something in and it works, but it leaves you feeling a little uncomfortable. There's just too much about it that you don't understand. It's a nagging itch that you want to scratch: what exactly is going on in there? Personally, I had this feeling with log4j - a deceptively simple little library with a surprising amount of depth. (And actually I'm still not entirely clear how commons logging, java.util.logging, and log4j all mesh together, even though I'm pretty sure we're talking about like 20 small classes).

Over time there are these "idea" technologies which just don't make sense unless you know the idea behind them. Spring is perhaps the best example of this. Learning the control flow of a Spring app without prior knowledge would be like learning French from a French dictionary. It seems like there are lots of idea tools out there, and more every day. Most of them are NOT amenable to quick uptake.

It would seem like most library authors would enjoy having you become an expert in their library, to become passionate about it, to understand it's delicate intricacies - especially the idea-driven tools. But often this just doesn't happen. Why not? Because when it does it is by persistent necessity rather than inclination. Consider Spring: people learn it because they use it for project after project. It is a persistent feature of the application landscape. It pays to learn it, and to learn it very well. But Sax? Or Java IO? Or Swing? You might need it occasionally, but there's no reason to dig in. Ignoring these libraries is a smart play.

The technology that seems to do the best are those rare gems which are both easy to adopt when you're in a hurry, which are broadly useful across a lot of projects, and which reward the student as they get deeper into it.

These observations drive a few conclusions. First, for an application programmer, be kind to yourself and recognize when you're running and gunning, and when you're taking your time to savor the moment. We will always experience a combination of both modes, and neither mode is better than the other, so don't berate yourself for not taking the time to learn that library better or using it to it's full potential. You didn't have time, and 99% of the other users didn't have time either. Second, for the library author, recognize and embrace those two modes because they are both important. Too often you make it difficult for us to use your libraries, expecting us to know magic incantations (class casts, method chains, constants) to accomplish straight-forward tasks. I have no doubt that the complexity is necessary to handle edge cases: but that's not why I'm using the library! I'm using it for the core case. Give me a utility class and mark it clearly as such (oh boy, nothing slows people down like trying to figure out dueling utility classes, abstractions on top of abstractions done with different idioms within the same project, and finding out that they were just facades over the *real* library). For God's sake use package level JavaDocs liberally to explain how the pieces go together with simple example code, and make some reference to applicable utility class in the lower level classes.

It's not easy being a Java programmer, and it never will be. Our language's expressivity is inherently (and intentionally) limited in the hopes that the compiler and other programmer tools can make our programs more error free. This trade-off between safety and freedom makes it all the more important that our libraries be incredibly well-designed, because we just don't have the linguistic freedom to mold your library to our liking.


No comments: