Chris James

Developer and other things

Estimates

Published on 29 December 2015

Why do developers whine about doing estimates? All the business wants is just some kind of assurance that their important project will be done by a given date. What’s the big deal?

Let’s be clear here, estimates are always wrong

That’s not the worst of it. When you lock your development team in a room for a few hours to try and estimate 100 stories you are now suddenly back in the waterfall world. You are committing yourself to a set piece of work that cannot change.

Which is what I thought as an industry we had got past. These are inarguable facts about software development

  • Priorities change
  • Knowledge (about a system being developed) changes
  • Teams change (they get better, usually)

Not only is it impossible to say “40 features will be delivered by April”, but you shouldn’t want to either!

In X weeks time, you will have a better understanding of what you want and the development team will be better equipped to help you make those decisions. Upfront estimations take you away from this.

The estimates I do like

  • A finger in the air estimate of a bunch of high-level features can of course be given. These are ok because everyone knows that they’re vague and subject to change
  • Relative weighting of features. This is actually the only estimate that’s important because it helps the business make a decision based on a sense of reality.

Estimation sessions

“Estimation sessions” where a gigantic pile of stories are dropped at the feet of developers locked in a room for a few hours, points to big flaws in your process.

It doesn’t acknowledge that change happens

Only when you actually start doing the work do the real problems you’re facing become clear. There will be stuff you missed which will effect your to-the-day timescales.

It implies you’re doing mini waterfall, not agile

I am often astonished when I see these huge piles of cards. Where have they come from? What happened to the principles of lean-ness and doing just the work you need and then moving your priorities as and when you need them?

You have done the “analysis” stage of waterfall already it seems. You have looked into your crystal ball and worked out all the features that your customers need.

The software project fallacy

You have a deadline and I understand this. I hope you understand that if your software is worthwhile that it will still need work on it after your deadline. If it’s not worthwhile, why are we building it?

At the very least it will need maintenance but if your software is actually good, by setting a hard deadline you are really shooting yourself in the foot.

People often forget that what’s really good about software is you can change it. The industry has dedicated so much energy in trying to make software malleable, yet so often we are poor at selling this to the people paying our wages.

By setting hard deadlines you are creating a precedent that you know what your customers want and that their needs never change. Quite the claim.

Go back to basics

Build, measure, learn over a small handful of the most important features. Discover what features are actually important and get it right. Everyone will learn about the product and you may develop something completely unexpected.

If you do this in a collaborative way with the business you will get out of the mindset of software being a static thing that you make and throw away.

If the parties engage together they can make something better. The software development team is not seen as a cost-centre but an asset that can actually respond to changing needs.

Summary

Fine-grained estimations disregard many of the good principles around lean, agile software development. Instead of trying to predict when a set-in-stone list of features will be done, acknowledge the unknown of business needs and if you create a truly collaborative team you can build a better product than you imagined.

You cant escape deadlines. But you should be focusing your efforts on building a team that works hard at becoming efficient at writing maintainable, useful software by working with the business/customers and responding to changing needs.

There is some interesting debate around this on twitter

Terror Handling

Published on 20 November 2015

The Happy path of writing software is usually the easiest part and coincidentally is the the thing focused on most during estimation. A lack of thought behind error handling can have big consequences on the long term health of a code base.

I am going to contrast on the 3 main methods of handling errors that I have come across, exceptions, product types (i.e tuples) and sum types (Try, Either, et al).

The problem with exceptions

On the face of it exceptions seem convenient but most people understand that you need to apply a lot of good practice for them not to be a pain. There is countless literature about the misuses of exceptions, from Pokemon exception handling to using exceptions as control flow.

The best use-case for exceptions is when you “know” it can’t be recovered from. The problem is exceptions tend to be conflated with normal errors that you do want to recover from.

When you use exceptions like this then it impacts code re-use. By throwing exceptions you are losing referential transparency, which means you cannot trust the type system; getFoo might not return a Foo for all inputs (it is not a total function). This means that reasoning your code becomes more difficult (because you need to check the source to see the real behaviour) and it is harder to simply plug functions together.

Product types to the rescue?

The debate around error handling is fairly prominent in the GoLang community, mainly because it doesn’t really* have exceptions.

The language supports tuples so the convention is to simply return the error to the caller if there is one.

In this case we are referentially transparent, the higher order function lets us know that it wants a function which could return an error and will act on it.

This explicitness means you don’t have to look into the implementations of functions to check for exceptions being thrown and the compiler (and tooling) will complain if you try and pretend a function could never return an error.

There is a better way

In simple examples it doesn’t seem so bad, but a lot of Go codebases are littered with these kind of checks. The main problem is that it is very difficult to compose potentially failing functions into new functionality.

Scala (and lots of other strongly typed languages) lets you write sum-types which allow you to encapsulate these very common computations in the type system in such a way that you can be explicit and still write your code in a declarative and convenient way.

As you can see, i am declaratively gluing the functions which could fail together. If they fail at any point then the result becomes a DomainError and doesn’t call the following functions.

It’s important to note that the respective functions don’t “care” about this composition, i didn’t have to do anything special other than declare that there might be an error using the type system.

This approach has the referential transparency of Go whilst being more convenient and declarative

Summary

When you raise errors to a first class citizen in your code by asking the compiler for help, you improve the re-usability and understandability of your code; not to mention it will be more robust as you won’t be having uncaught exceptions flying around.

As your type system becomes more expressive the perceived convenience of exceptions over explicitness disappears.