Sep 11 2007
Development Acceleration: The Second Derivative of Functionality
(Edit: Went through, edited, and updated. ~~ Robert.)
So, Brian beat me to the punch: he’s posted about The Second Derivative of Programming, which is an idea that we’ve been kicking around for a while over the phone. It’s a good post, and I highly suggest tackling it.
(Note to self #1: Remember to trademark things in the future.)
(Note to self #2: I hope Brian’s doesn’t trademark those things I steal from him.)
While Brian states the second derivative of programming in terms of code and code capability, let me take things a slightly different tact. I’d like to think in terms of functionality and business solutions, and see what that means for the lives of developers.
Let’s first get a grasp on what I mean when I say “The Second Derivative of Functionality”.
For a technical description of a second derivative, check out Brian’s post or this write-up on second derivatives. Colloquially, the derivative is a measure of change*: positive derivatives mean forward change, negative derivatives mean backward change. So, in the case of distance, the derivative is the change in distance, otherwise known as speed. The derivative of the derivative is called the second derivative. Again, in the case of distance, the first derivative is speed, so the second derivative is the change in speed, otherwise known as acceleration. (*For the mathematicians in the crowd, I am always talking about derivatives with respect to time.)
When I say “functionality”, I mean it in a business and not technical sense. Functionality is the application of technology to a business solution. Adding a new method is not functionality — even if it enables the code to do something it didn’t do before — until you apply that code to solve a business problem. Note that a given piece of code can provide a lot of functionality by playing in many different roles: the classic example of this would be the POSIX utilities like cron and grep. On the other hand, functionality can be lost even in a stable code base by shifting business expectations: “Until that code is changed so it stops doing X and does Y instead, it’s worthless.” / “But you spec’ed it out at X!” / “Yup. But now we need Y.”
So the second derivative of functionality is measuring not the speed at which functionality is added, but whether it is becoming easier or harder to add new functionality.
As a tech lead, my eye was constantly on that second derivative. If I could keep that positive, I was constantly offering the business new functionality, faster, without pushing my team harder. And that resulted in the business being happier, and the developers actually getting more time for technical clean-up and rework as the project moved along.
The common trap, though, is to think of the second derivative as being a magic bullet piece of code: that somehow you’ll strike gold with a configuration of code which will kick up the momentum. I’ve seen a lot of true-blue programmers who became “tech leads”, and addressed slowing development momentum by calling for more advanced frameworks or standards — I’ve seen this happen a lot of times, and I’ve never once seen it actually help. If you really can get to that piece of magic code, then more power to you. I, however, have never encountered such a piece of code. So I needed to go looking.
The first way that I managed to improve the second derivative is by having developers who understood the problem space, but built the solution through iterative development. These are the keys behind successful Agile implementations, and it’s easy to see why once you’ve seen it work. By keeping communication between business people and developers open, the developers understood the problem they were tackling. This meant that they had a good intuition of when it was okay to specialize a solution, and when they are going to need to generalize it. This means that the new work coming down the pipeline won’t need refactoring for generalization, but the code also doesn’t need overblown configuration for specialization. That tendency is amplified and reinforced by working only small pieces at a time, the business has a chance to jump in and correct functionality problems early. This prevents burning time on large code bases which never get to actually become functionality — when that happens, the developers have to rework the code base, which not only takes time to rework, but also saps the momentum and morale out of the team.
Up-front investment in architecture and architecture-through-analogy were another technique that I adopted to increase the second derivative. This is a bit of Agile development heresy, but my experience has consistently shown that the up-front investment in architecting the code pays serious dividends by identifying where the extension points of the code will be, and preventing experimentation and varying designs from making a muck of the code base. Further, you will be doing similar things very often if there is a consistency in architecture, which opens up more opportunities for Brian’s “re-use”.
The style of architecture also mattered to me, although it may have just been my own approach. However, I have found that when describing a piece of code, it is best to describe it using real-world models. My favorites are probably pipelines (”Do A, then B, then C, then D.”), boxing/facades (”This boxes up that information.”), delegating (”Hand the Foo off to be Barred, and then…”), and asking (”The controller asks the service for the information.”). By sticking to these real-world examples, developers can quickly get an intuitive understanding of the domain of influence for each piece of code, and they gain a gut-check for when they are starting to go astray. This allows for a maintainable and clean code-base without profuse documentation or obnoxious, awkward diagrams. Documentation and diagrams make for poor guides when it comes time to extend the code, and having to wait for an architect to make a decision and update the documentation adds serious delay into the development process. If you can’t describe the code that way (and some code just doesn’t lend itself to it), then keep the ugliness limited and abstracted away in a library.
While architecting and coding, try to solve the smallest possible problem, and then leverage those small solutions into bigger ones. Look at the text munging utilities on Unix like grep, cut, and sort. Each of them solve a single problem (within handwave), and can pipeline them for some pretty impressive feats. Programs should be like that: when you’re writing a class or application, don’t make it particular. The particularities should be passed in or delegated out. Particulars will have to be pulled out or coded around in the future. This is one of the beautiful things that functional programming does well, and it’s easy to do poorly in less rigorously-typed language. This is also a major principle behind service-oriented architecture, which is part of the reason I’m so taken with that approach to architecture.
The second best thing I know of for that second derivative, though, is an emphasis on regular integration/release with automated build, testing, and deployment. The code base is like a dog: it needs to be taken out for a walk every once in a while. And that doesn’t just mean letting it out into the back yard to see where it makes a mess, that means really taking it out for some thorough exercise. To do the thorough exercise, the code needs to have challenges — whether that’s QA work, acceptance tests, or users or pseudo-users beating on it, that’s fine. The challenges just need to be there, so the problems and new features are discovered soon.
The best thing, though, is simply morale. Keeping morale high among the developers will result in better code being written, better communication with the business, and an all-around improvement. Unfortunately, that’s also the hardest one to get in place, and I’m at a loss to try to explain how to keep morale strong. I can give you general principles that seemed to have worked for me, but how to apply them to any particular circumstance requires a kind of knack.
Does anyone else have thoughts on the second derivative of functionality, team morale, or other issues?
Popularity: 25% [?]







I have taken a stab at answering the moral question as well as my own take on the second derivative. Take a look.
I think you have the causation wrong- generally, nothing is as harmfull to programmers moral as lack of productivity. There are exceptions (in both directions), but as a general statement, so long as things are moving forward, programmers are happy. And they’re at their happiest (generally) when they’re the most productive. But the happiness comes from the productivity, not the other way around. This is why you become a programmer- it’s not for the money (you become an investment banker for the money), but because you like writing code that works. The thrill of victory.
This is one of the reasons I think agile programming works- it gives a regular stream of “rewards”- in the form of working code and milestones met- to the programmers. They can see the progress being made. This encourages programmer moral- look at how far we’ve come! See all this stuff we’ve done! Here, let’s take a look at an *old* version of the code- see how clunky and limited it was? Isn’t this cool?
It helps not to piss on your programmers too- I’m not saying this is the only thing that has an effect on programmer moral. But it’s a major one.
Actually I can see both sides of it in more of a feedback loop of sorts. Happy programmers are productive ones, and the most productive programmers tend to also be the happiest ones for a variety of reasons.
On the flip side of that however I have known amazingly productive programmers to be amazingly unhappy because despite their efforts to get things done (which they have accomplished) they are not ‘changing’ the over all structure for the better, just delivering the functionality that they have been asked to - Causing a feedback loop of a whole different nature. A feed back that takes moral down and causes an overall slowdown because while things are being developed the system as a whole is not being cared for.
Thank you for your input and commentary - GREAT conversation in my opinion.
My experience is that good morale will lead to good code — the inverse does not hold. While I was a tech lead, we built some really good code. After I left, morale broke down because of the invasion of the business culture. The code quality then tanked.
My own thoughts suggest that yeah, good morale leads to good code. You can get along for a little while without good morale (death march to the new year) but it comes back to bite you.
[...] like me over at “Development Acceleration: The Second Derivative of Functionality“, where I defined “functionality” as business value realization: Functionality is [...]
[...] take a lot of work to do right (where I define “right” to include 7 Useful Things and Development Acceleration), and I’ve been busy with work on one hand, moving to Durham on the other hand, and trying to [...]