Ask For What You Want
When talking with like minded colleagues at work, I have occasionally said “ask for what you want”, expecting to get a knowing smile, nod or wink in return. I only ever got blank looks back. Sadly, I’ve checked online and “ask for what you want” is really not a popular heuristic in the world of programming and not even in the much smaller world of functional programming. It’s not all bad news, it does mean that I can claim this one for myself.
My First Rule of Programming, Life and Everything
One reason that it’s not a popular phrase is that I phrase it in a general way rather than just in programming terms. I do so because it is also an approach that may even apply to life as a whole – in keeping with the theme of the blog I am still collecting data and ruminating on it – but the indications are good. In fact, so good that “ask for what you want” is my First Rule of Programming, Life and Everything. I call it my first rule to distinguish it from my other rules of Programming, Life and Everything which don’t exist yet. It’s always a good idea to version your data since you will almost certainly need it later and even if you don’t then it costs next to nothing. I’ll throw that little tip in for free.
Programming: Ask For What You Want
By way of a concrete example to illustrate why the component parts of your programs should obey my rule, imagine we have a document editing web app coded in Javascript which uses a third party system to record what the user is doing in the app. Let’s suppose that the app itself allows you to flick backwards and forwards between documents, saving your changes back to the server and saving more temporary data about how you had that document configured while you were editing it, I’m thinking of text zoom settings, cursor position and so on – things that don’t need to be saved on a server somewhere but remembered such that if you immediately returned back to a document then your software would remember the size of the text and where your cursor was positioned when you were last editing that document.
Because the document editor code is carefully thought through it doesn’t wait for the data to save on the server to start downloading the next document. Imagine that the document editor has code like this:
1 | const loadDocument = (saveDoc, loadDocId) => { |
The save
and load
functions are similar, they tell the third party service for recording user activity data, manifest in the code below as the customerIntel
object, the type of event that happens and then orchestrate the work:
1 | const save = doc => { |
The save user data code sends an event first and does its actual work after that. It looks a bit like this (and the other functions follow the same procedure):
1 | const saveUserData = docId => { |
Which is to say that to use the third party service for recording usage, you must tell it about the type of event and the name of the actual event. For your convenience it’s set up so that you call just a method called setEventType
once to tell it the type of event, and call the event
method with data relating to that specific event.
This service does not follow my first rule of Programming, Life and Everything because the event
method wants to know three things: the type of the event, the event name and some data, but it only asks for two. Instead of asking directly, it goes to the shelf where the setEventType
method keeps the event type data and gets it from there. The service has an implicit but not enforced order of events requirement – you need to call setEventType
before you call event
. In the simple case, the absent minded programmer might just forget to call setEventType
. That problem doesn’t exist in our example but something worse and less obvious does. Saving and loading are happening at the same time, there’s no guarantees at all that when saveDocument
runs that the event type is still “Saving”. It’s likely that by the time saveDocument
runs the eventType will be set to “Loading”. It’s entirely possible that the data saved by the third party service looks like this:
Type | Event | Data |
---|---|---|
Saving | User data | DocId: 1 |
Loading | User data | DocId: 2 |
Loading | Document | DocId: 1 |
Loading | Document | DocId: 2 |
It’s possible that it behaves this way on one user’s computer and yet it might be correct or different on another user’s computer. It might happen to work fine for people who test the software for defects.
Imagine too that in future, someone higher up in the organisation will pull down the data about how the software is being used. They may end up with a graph like this:
They likely want to be data-driven and may say things like “saving just isn’t that important for our users” and de-prioritise fixing saving bugs or they may even change the direction of the product – sending the development team away for months to radically change how it works for entirely misguided reasons.
The effect of a simple little flaw like this could be huge. It could create not so much of a butterfly effect but more of a blast radius.
The good news is that there’s a simple fix that could be made to the customer activity tracking service and you already know what it is. If the event
method wants to know what the type of the event is, then it should ask for it – ask for what you want. This trivially simple change eradicates all possible crosstalk between different events and event types. An entire class of bugs is vapourised!
There’s much more to say about why this approach makes sense and what the benefits are. For the sake of brevity here, I’ll leave that for another time.
Ask For What You Want: Life And Everything
This part of my rule is harder to illustrate and instead I’m going to try to sell it to you on a logical basis. Typically, asking is cheap and what you want is by definition quite a big deal. All other things being equal, where the costs are negligible and the potential pay-off is large, that’s a deal you should take. Ask for what you want.