Tuesday, October 03, 2006

Good Ideas Taken Badly

It appears other people had a similar reaction to Steve Yegge's Agile rant. The funny thing is that as wrong as I think the basic argument is, it has a good core of thought. Somehow it went astray. It's a bit scary how thin that line really is. You know, how a set of good ideas and good principles can appear to be justifying a bad argument. That, ironically enough, is exactly what Yegge attacks Agile for, when he points out how the short cycles can be used to make a project more date focused, rather than less as Agile is intended to.

It is a risk, when you talk about short release cycles, that managers will treat them the same as the old release cycles, but expect them more often. But when properly used, an iteration is more of a goal than a make or break moment. Sure, you put out a build, but there are no guarantees any specific feature will be part of it. Whatever is done is what's done. And you use what you learned about your velocity to predict the future. But predictions should remain just that, predictions. Not commitments. And they aren't that way just because Agile says so. No, it's because the incremental releases relieve pressure and present clear alternatives.

High Tech Agile

But the possibility of misuse isn't his only criticism of Agile. He also attacks many of the "low-tech" solutions, such as pair programming, whole team, and story cards. These arguments actually have a ring of truth to them, because it does feel like there should be a better way. A way that doesn't require all of the trade-offs, or at least not as many as these introduce. But that feeling is irrelevant, at least in an immediate sense because these low-tech solutions are better than the pre-existing alternatives.

Yegge does offer up a high-tech alternative to story cards though, and as I've written it's very interesting. The only problem is it's inaccessible to most of us for the moment. I'm sure that will change, but in an immediate sense, the best options available are the low-tech variations. Thought into how to evolve these practices further through technology is certainly justified.

For example, I'm starting to believe the concept of an office will go the way of the dodo, at least for programmers. Despite its sensibility, sitting together has always bothered me because of the lack of privacy. Sure, you can provide private spaces, but then you have to switch spots, and deal with all the associated hassles. Plus, what if the team next door is just too loud? Or what about people with bad hygiene or simply annoying habits. That kind of environment is extremely fragile, and unless someone is intentionally obnoxious or inconsiderate, rather than just dealt an unfair deck (smelly, sneezy, etc.), it's hard to justify their removal from a moral or legal sense.

My solution is to use technology to create a virtual shared space. The beauty of this is that you can turn it on or off, and selectively include or exclude parts of the team. It's dynamic, and possibly best of all tackles one of the largest hurdles, the remote worker issue. Unfortunately the tech just isn't quite here yet. It's coming, no doubt, and pieces and parts are here today in various forms of quality and incompleteness, but it's not yet complete. And considering how difficult it is to argue the case for a second monitor for every developer, it's probable that when it is here, it will be difficult to argue the case for the proper equipment.

Pair programming is another piece that would benefit from this tech, and the greater dynamism. But pairing could also benefit from several other techniques that are doable today. Another blogger writes an interesting way of doing parallel pair programming (read the end). I've often thought about just plopping down a few extra monitors on a developer's desk dedicated to watching what his pair is doing, thus allowing them to collaborate without one of them being relegated to the stone ages of paper and pencil (or more commonly marker and plastic).

Back to the Point

Agile is definitely improvable, definitely full of flaws, but rejecting it in favor of the old way isn't right. I don't think this is what Yegge meant, but it's what more than a handful unfortunately read. It's not an uncommon problem either. We often make the mistake of attacking the solution to one problem, because it's not quite perfect, while ignoring the real problem. Why are people more concerned with rewriting Java programs when they have a heap of COBOL code lying around? Both have merit, but one is a far bigger problem. I'm sure part of the issue is that rewriting the Java code is less difficult, but COBOL code isn't going to update itself, and the number of people willing to even look at it is shrinking faster than the amount of deployed code.

Unfortunately there's no general solution to this problem, because you can't always say one end is right, and the other end is wrong. A few issues gradate evenly from black to white, but many others are a mixed bag. The best examples here I can think of are the static/dynamic debate, and the browser/client debate. Personally, I believe that static is the "right" way. But there are a lot of great things about dynamic languages like Ruby, and if I took a black and white view, I'd ignore that. Learning and using Ruby has opened me up to these advantages. But for every advantage so far I see a counter.

For example, unit testing is beautifully done because of the flexibility afforded by the dynamic nature. But on the other hand, I find some of the unit tests I'm writing implement a hand-coded custom version of static analysis. Not typing variable types can speed things up a bit, but I find I lose much or all of that to extra syntax debugging due to a misspelled variable name or such, and the problem that I may need several test cycles to find consecutive syntax errors, rather than one compile cycle (or a squiggly).

For this last part, syntax debugging, better Ruby IDE's can certainly help, but there isn't any reason a static language can't use type inference to remove 95% of the extra typing. Likewise for the first part, unit testing, there's no reason static languages couldn't make a special exception to type checking, encapsulation, etc. in unit tests. The JVM and CLR have all the necessary pieces and parts to support this. The only downside might be speed, but how fast your unit tests run is not your number one performance concern. (And a static language faking dynamism through reflection is still likely about the same speed as the natively dynamic language.

Clearly this is an area where both sides have a lot to learn from each other, and the best solution lies somewhere in between, not at one end or the other. My belief is that it will be easier to add dynamic features to static languages, than the other way around, but other than that, I see value in both arguments. My real point here is not whether static or dynamic is better, it is that a dynamic or a static language advocate both have a set of good arguments that can easily be used to justify the wrong conclusion. That conclusion is that everything the other side believes is wrong because static and dynamic are opposites and in their minds, wholly incompatible. It's not true, but it's a case where the truth is easily and often ignored.

Browsers and clients are another great example of this same problem. Since I'm not going to take the time to explain my belief of which is ultimately the "right" way, I'll simply direct you to a similar viewpoint. Curiously another entry from Yegge.

2 comments:

Ryan Cooper said...

Great post. Steve's rant against Agile reminds me of an old saying "perfect is the enemy of good enough."

chromatic said...

Using technology to replace such things as story cards and sitting together seems great, but you give up a lot of the benefits of the low-tech solutions. It's well-worth considering the tradeoffs there too, rather than dismissing them facilely ("I don't like sitting next to smelly people!" "You can't grep index cards!")