Software Development And The Sunk Cost Fallacy

SunkA large group of lumberjacks are cutting down trees in a forest and doing a really good job of it. Trees are falling left right and center, everyone is working with focus and tenacity. During a lull, one of the lumberjacks climbs up to the top of the biggest tree still standing and sees that in all the confusion to get the work started, they’ve made a bit of a mistake and should infact have been cutting down the forest next door to the one they’re in. So, he yells down to the rest of the team:

Hey guys, I think we’re in the wrong forest!

To which the foreman yells back:

Shut up! We’re making progress!

I don’t remember where I first saw this story (_I guess that’s the one downside to reading a lot of books :)_). But, this story (or one very similar) is actually a commonly used leadership metaphor. It is often used to demonstrate the difference between leadership and management. As interesting as that may be (and it is actually interesting enough that I might look at it further at a later date), to me it also demonstrates another common phenomenon – that of the sunk cost fallacy. You see the foreman, wasn’t really an idiot, he knew the climbing lumberjack was right. But the team had invested so much time and effort already, it would be a shame to waste it. Then there is explaining the mistake to upper management – could get awkward, plus think of all the paperwork. No, it is way too embarrassing and costly to admit the mistake, better to pretend that this is the way things were meant to happen all along, hopefully it might all turn out for the best and we’ll be able to salvage the current situation.

The Sunk Cost Fallacy

The sunk cost fallacy, also known as the Concorde fallacy, is a very interesting phenomenon. What it basically boils down to is the fact that it is human nature to throw good money after bad. The more resources (time, money) we invest in something, the more likely we are to stick with it despite all the indicators of our venture being a failure (I am not going to give generic examples; you’re welcome to check out the links above). It is therefore no big surprise that when it comes to software development, we’re not immune. Infact we take the sunk cost fallacy to new heights of awesome :).

In the world of finance, the sunk cost is accepted. If the money is spent and can’t be recouped, it can no longer influence any further decisions. On the other hand, in software, once we have spent any kind of effort/money on a feature/project, we just can’t let go. We would much rather delude ourselves and everyone around us that we can still turn everything around and make it all come out for the better. Developers do it, managers do it, it’s an industry wide trend. No matter how flawed the product vision turns out to be, we are much more likely to try to adapt the whole ecosystem to the flawed product/feature rather than starting over from scratch and building something that will better fit the ecosystem we have. More than that, we will go to great lengths, bring in extra people, do overtime, whatever it takes, as if we can make an incorrect decision right by sheer force of will and sweat. I am not just talking at the project level, even at the code level we (developers) will often stick with a technology/library choice through thick and thin long past the time we should have abandoned it and found something that fits our needs better. There are always, good reasons to justify all this, but what it comes down to in the end is self-delusion  – the sunk cost fallacy at work.

Lalalala, I Don’t Want To Hear It

I once worked on a product that started out as an offshoot of a bigger project. Initially it was only adapted to work as part of that bigger project. But, after a while a decision was made to turn it into a framework. There was nothing wrong with the idea. This would have been a perfect point to abandon the existing code; it was unwieldy and difficult to work with. It would have made sense to merge it into the bigger project and start from scratch. But noone was willing to make that decision, money had been spent on development, it was practically a framework already, just needed a little extra effort and then we’d be able to use it on all the other projects in the company and save all kinds of money. A business proposition too good to refuse! Except, in trying to munge the existing code into a framework, everything became even more unwieldy, no project really wanted to use it. But, it was decided that the situation could still be salvaged, all we needed to do was turn the framework into a full-blown product. Once again not a bad idea on its own, and had we started from scratch here, we may have come up with some cool stuff, but we couldn’t just abandon all that ‘good’ code. So, we went on another retrofitting exercise, building more code on top of ever shakier foundations. At this point the ‘product’ had a terrible reputation within the company, noone except management wanted to have anything to do with it, but that just meant it was pushed even harder.

The company wasn’t willing to make the necessary decision to either abandon the project all together, or to start over and build something solid. The money that had already been invested was guiding all the decisions. Recouping losses was the word of the hour and in pursuit of that goal even more money was sunk into a venture that didn’t deserve it. If this were an isolated incident it wouldn’t be so bad, but this story probably sounds awfully familiar to many and there are more than a few horror stories that are way worse.

Delusion Industry Wide

How about an example of sunk cost self-delusion at an industry wide level? You need go no further than JavaScript. I don’t want to bad-mouth the language it has done some decent service and I won’t deny that it has some good parts. But as that photo I saw a few weeks ago clearly demonstrates, there are good parts and then there is the rest.

Javascript

People tolerate JavaScript but most developers don’t really love it. It can be unwieldy and hard to use, some things just don’t make sense and yet it has become the de-facto language of web 2.0. It’s not as if there are no better scripting languages around, and even if there weren’t, it’s not like we can’t come up with anything better if we tried. But, all the browsers already support it (well, kinda, none in quite the same way) and there are all the frameworks that make everything much better. No, there is way too much invested in it, I am sure we can make it perfect eventually. In the meantime it makes a lot more sense and is infact much easier, to put millions of developers through daily pain, rather than phasing out JavaScript in favour of something better (anything would probably do). Seems like sunk cost fallacy at its finest. Admittedly though, I am no JavaScript guru, so if you are, please come along and tear my argument apart.

End of the day, there may not be much that each one of us, can do to affect grand change at an industry-wide level, but we CAN influence the projects we work on. If you see the beginnings of the sunk cost fallacy rearing its ugly head, don’t stay silent. It is never too late to remove a technology or library if it was clearly the wrong choice. Be ruthless, if it doesn’t do the job the way it should, get rid of it, find something better, there are always alternatives. For the management the advice is the same, just at a higher level. Don’t keep throwing good money after bad. Remember if all the other lumberjacks (including the foreman) had just stopped and taken notice when the first one told everyone of their error (regardless of the embarrassment and inconvenience), they could have avoided cutting down the rest of the magical woods – home of the unicorn (cause that was what they were chopping). Instead they could have started chopping the dark dreary forest, like they should have been doing in the first place and thereby made life better for everyone, including themselves.

Image by amateur_photo_bore

A “FizzBuzz” Faux Pas

fizzA little while ago while writing this post, I came across the post by Jeff Atwood where he talks about the FizzBuzz test (_originally found here_). I remember seeing that post for the first time a couple of years ago and thinking that I would be a little insulted if someone asked me to write something that trivial in an interview. Seeing it again the other day I realized that my feelings hadn’t changed. It IS an insulting question. Sure you may quickly weed out complete incompetents by asking it, by you will also alienate just about every competent developer. There is really no reason to ask a question that simple. You might as well ask something more complex, that could really test a programmer’s skills. The incompetent will still have no chance, and you won’t make the decent developers feel like you’re making fun of them. If you can’t think of any interesting programming questions to ask (_and you don’t like my quine question :)_), I will try and cover a few decent, straight forward coding questions at some point in the future. But, that’s not what this post is about.

You see, when I was reminded of the “FizzBuzz” question, what I actually thought to myself was something along the lines of:

What an insulting question, I could do that in 10 seconds or less!

Of course having thought that, I immediately had to prove to myself that I actually could do it (curse you developer personality :)). So, I took the subsequent 10 seconds to come up with this (in Ruby, of course):

ruby (1..100).each do |index| if index % 3 == 0 puts "fizz" elsif index % 5 == 0 puts "buzz" elsif index % 3 == 0 && index % 5 == 0 puts "fizzbuzz" else puts index end end

Trivial right?

Did you spot it yet? What I gigantic fail on my part. Here is a snippet of the output:

...
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizz
16
...

Everything is fine until we get to 15 and – no “fizzbuzz”. Of course, there is no way we could ever get a “fizzbuzz” with the above code. If a number is divisible by 3 AND 5 it must be divisible by 3 OR 5 and so the first two conditions of the if..else block would match before we ever get to the third one. It should have been this:

ruby (1..100).each do |index| if index % 3 == 0 && index % 5 == 0 puts "fizzbuzz" elsif index % 3 == 0 puts "fizz" elsif index % 5 == 0 puts "buzz" else puts index end end

Now everything is fine:

...
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
...

The lesson here is this. It is never a good idea to write code mindlessly. No matter how trivial you consider a problem to be, don’t just switch off and write it on autopilot. Even if it was only going to take 10 seconds, take a few seconds more to think, before you jump in and then take another 10 seconds to make sure you didn’t miss anything once you’ve finished. Not only will you write better, less buggy code, but you will also never end up in one of those embarrassing situations where you feel insulted by a “fizzbuzz”-type question and get it wrong anyway :). It just doesn’t pay to mentally switch off in our line of work. I thought that little snippet of wisdom was worth sharing and even if you already consider it common sense, it never hurts to be reminded.  

Image by Vidiot

On The Mastery Of Teaching

TeachThey say that those who can – do, and those who can’t – teach. This makes me sad for two reasons. Firstly, the general standard of teaching these days is abysmal. From pre-school all the way to university, it just doesn’t seem like the people who teach are the best and brightest any more. Sure there are still occasionally some brilliant people doing the job, but overall the profession is not in a good place, or is this just an illusion? It’s actually worse than that, especially at higher levels where people go into academia to do research (or whatever) and treat teaching as an annoying distraction they have to deal with, so that they can get back to their pet projects. And this I think is the real problem – at least at the higher education level. It’s not that the people who teach are not smart enough; it’s just that they approach the act of teaching in a half-arsed fashion. They have skills/knowledge of their subject matter, but have no teaching skills and don’t really want to develop any. Of course, the students can only judge their teachers by how well they teach and so we end up with the current sad state of affairs (where just about everyone can relate to sayings like the one above) and this is the second reason why I am sad.

I’ve been reading Polya’s “How To Solve It” and it got me thinking about what it takes to be a good teacher (and a good student, but I will leave that for another post). I’ve talked about mentoring and software apprenticeships before, but that was more of an on-the-job deal. What I’d like to do is focus purely on the skills you need to be a great teacher in the true sense of the word.

By the way If you haven’t read “How To Solve It”, I highly recommend you pick up a copy, not only will it help your math skills (infact it takes the number 2 spot on my list – which I am yet to finish writing :) – of books a programmer needs to revive his math skills), it will jazz up your general problem solving abilities and as developers, we can never have too much of that.

Being A Great Teacher

Many people are of the opinion that as long as you know the subject matter, you can teach it. Nothing could be further from the truth. Having programming knowledge doesn’t make you a good developer and this goes double for teaching. I see a good teacher as an extremely well-rounded individual, knowledgeable, passionate, a showman with excellent interpersonal and communication skills. Consider that the job is to impart knowledge and teach the student how to solve problems. Not solve the problem FOR the student, but equip them with the ability to solve the problems themselves. This often requires extreme patience and the ability to put yourself in the student’s shoes (i.e. empathy) no matter how many times you have been over the same material. Just think about how you would explain a subject that you know really well, to a person who knows nothing about it (like explaining software to a business person, for example). There is a reason why every company wants developers who can talk business language, because most people find it really hard to explain their professional domain in layman’s terms. For a teacher, this is a core part of their job. So, good people skills to be able to understand the student and good communication skills to convey the material, but why showmanship?

A teacher is basically a public speaker, it is just that they mostly speak in the same place and usually do it far more often than your regular speaker. It doesn’t matter who your audience is, whenever you speak in front of people it is your job to keep them entertained and take them on a journey. They should be excited about what you have to say, a good speaker can do this with the most boring of subjects. But a teacher’s job is even harder than that because you want to keep the students interested enough so that they are eager to come back week after week. You think this is a bit overkill just to read a few lectures? Well, we are talking about being a good teacher not a mediocre one, there are plenty of those around, I should know I’ve slept through most of their lectures and that’s when I was actually there in the first place, instead of at the pub :).

Teach

What about passion and knowledge? I do believe the knowledge part is obvious, hard to teach something well if you have no clue, but passion is also paramount. You can never really convey to a student how important or interesting a subject is, when you clearly would rather be doing something else yourself. I think we’ve all had the experience of listening to a boring lecturer droning on and on, monotonously. Did it energise you into further study? Quite the opposite probably, it made you want to do something else, just so you don’t accidentally turn out like that guy. Contrast that with a guy who seemed really into what he was saying, he may even have been saying it badly and you didn’t really get it, but at least it sounded like it SHOULD be interesting, maybe even worth looking into further.

So, we have knowledge, professional skill, passion, communication skills etc. In short all the same skills that a good developer needs to succeed. What this tells me is that a good teacher CAN do, but they CHOOSE to teach. I really don’t understand managers who don’t try and build their management skills. I also don’t understand programmers who don’t try to build their programming skills and in similar vein, I don’t understand teachers who don’t try to build their teaching skills. You aren’t born with elite teaching ability, just like every skill you need to practice and develop. Repeatedly doing something badly, just to get it over with, is not practice.

I guess my point is this. If you’re ever in a situation where you have to teach others what you know, approach it like you would approach learning any new skill (like a new programming language). Get the basics down, practice, draw on your existing skills and knowledge, practice some more, prepare, research and follow that with more practice. Don’t give your students a reason to think that you couldn’t cut it in the “real world”.

Images by foxypar4 and cindy47452