Wednesday, October 22, 2008

Code, Forrest, Code!

The movie Forrest Gump has been re-playing a lot lately, and, as often happens, I see parallels in the software industry (I've learned not to bring these up to my wife so that I don't get the look). Of course, Forrest was mentally challenged, yet he had a wildly improbable life. The real point of the movie is the exploration of destiny vs. free will, as exemplified by the feather that floats freely, is captured and carried to new places in the Curious George book, and then floats free again. But that's not the point of this blog entry.

How did the mentally challenged Forrest achieve so much? Total concentration. If you notice in the scene where he first learns to play ping pong, the guy showing him says "The most important part of this game is to never take your eye off the ball". As soon as he says that, Forrest squints his eyes and starts concentrating hard on the ball, and starts hitting it. Of course, in the movie, he eventually becomes a celebrated table tennis player, going to China, meeting the president, etc. The events in the movie are highly improbable of course, but the writer had to come up with some talent that Forrest had that would enable all his amazing feats. And that was flow. I talk about flow in The Productive Programmer (in the Focus chapter) as defined by Michael Csikszentmihalyi. Flow is a state intimately familiar to all developers. It's that state of total concentration, where time disappears and you get your best work done. In fact, Csikszentmihalyi argues convincingly in his book that flow is the secret to a happy life: finding things that are challenging enough to engage your full concentration but not enough to be persistently frustrating. The ability to get to this state explains why so many developers love their career. Software development offers lots of opportunities to get to this state, offering puzzles that are always just within reach.

But flow doesn't come for free. It's a psychological state, meaning you can't just force yourself into it. My friend Brian Goetz has the best comparison I've heard: flow is like sleep. You can't force yourself to go to sleep, but you can set up the environment to make the state easier to achieve. That's one of the reasons people have so many rituals around bedtime. Flow is the same way. You can't force it, but you can set up the correct environment. Brian explained this to me in the context of interruptions. When he works at home and his family interrupts him, he's grumpy because they've broken his flow. But they don't understand: it's only a 5 minute disruption. But his killer analogy? What if someone awoke you 4 or 5 times a night for just 5 minutes at a time? You'd have a terrible night's sleep.

This matters a lot because perhaps the most hostile environment for flow is cube land. Putting developers (or any knowledge workers, for that matter) in a sea of cubes forces you to constantly deal with an environment that's hostile to getting to the state where you are most productive. Lots of developers have figured out how to survive (just like big city dwellers learn to sleep through noisy environments). One of my favorite lines from The Blues Brothers movie is when Jake comes "home" with Elwood, directly adjacent to an elevated train. Jake asks "How often do those trains run" to which Elwood answers "So often you won't even notice it!". How often do meetings happen in your office? So often you won't even notice that you only have about 2 hours a day to actually get work done. This is by the way one of the secrets to the effectiveness of pair programming. It is possible for 2 developers to get in flow at the same time. Because more than one person is working, external forces are less likely to disturb them, allowing them to stay in flow for long periods of time. This explains why, if you are new to pair programming, you are hammered after 8 hours of pairing: you've been in that deep concentration state for longer than what you are accustomed.

I talk about strategies for getting to and staying in flow in The Productive Programmer. That's the secret to real productivity when coding. Be like Forrest Gump: learn how to achieve that deep, deep concentration state in your environment (or, if you can't change your environment, change your environment). Code, Forrest, Code!

Monday, October 06, 2008

Library Oriented Programming

Way back in 1968, Edsger Dijkstra almost caused a riot at the ACM conference. His audacious crime? "Use of GOTO considered harmful." No one there could imagine writing code without GOTO's. Yet, of course, within a few years, GOTO-oriented programming faded away, replaced by structured, modular, and object-oriented programming. Structured programming has become such the mainstream that we don't even refer to that feature of the language anymore: we never say that C is a "Non-GOTO" language.

Fast forward to today. In the same way that C isn't a "Non-GOTO" language, I contend that Java is no longer an object-oriented language. Sure, the object abstraction is still there, but it has sunk so far down into the infrastructure we don't even think about it anymore. This blog really drove it home for me: Java is a library oriented language. Think about it: when was the last time you downloaded a single class from the Internet to use in an application? Libraries and frameworks are the code reuse mechanisms in Java. Ultimately, the class is just too fine grained to really achieve reuse, but libraries can.

This explains tools like Maven and Ivy. While Java is a library oriented language, no good facilities exist within the language to manage libraries. Some work has been done on the "module" specification, but word from insiders say that is has essentially collapsed into two warring factions: the OSGI vs. Maven camps. Consequently, it looks doubtful that a module facility will appear anytime soon for Java. That's OK: we'll keep doing what we've always done while waiting for ratification of infrastructure -- use open source tools that solve this problem.

Ultimately, we need to embrace the idea of Java as a Library-Oriented Language. That means treat libraries (and dependencies between libraries) as first class citizens in your projects. Developers tend to try to avoid nasty coupling and circular references with classes, yet too often tolerate it with their JAR files. Looking at Java in this light forces you to think about how you create project directory structure (Maven helps with this, as well as tools like AppFuse, which creates consistent directory structures for different kinds of web applications). Convention over configuration was one of the "breath of fresh air" approaches from Ruby on Rails. It makes building tools and plugins for Rails easy because you can always rely on a standard directory structure for projects. Of course, it's too late now to create the universal standard Java project structure, but you can do this within your own company. Once you have a consistent structure, it makes writing little utilities that can do things to all your projects much easier.

Consistency is the key to automation.

A consistent directory structure for all projects makes it easy to plug into continuous integration, write test helper classes, manage dependencies across projects, and a slew of other benefits. Start treating Java like a library oriented language, think hard about dependencies, versions, and where things live. And, finally, create consistency across projects so that you can take advantage of economy of scale.