By Stan Hanks, software engineering (it’s more than just writing code). Originally published as ‘As a non-programmer, how can I tell whether time estimates and comments like, “we can’t do that” are true/accurate?’ on Quora.
It’s hard, for non-programmers to understand just how complex developing software can be. You just tell the computer what to do, right? How hard is that?
Well, it’s deceptively hard, because the computer completely lacks what theorists have described as a knowledge framework. For instance, I can ask you to do something simple, like “bring me a ham sandwich”. You can quickly intuit that I actually mean “go to the kitchen, make a ham sandwich, and bring it to me” or “go down the street to the deli, order me a ham sandwich, and bring it to me” based on the context of where we physically happen to be and what has happened the last few times that request has been made.
You can further intuit, in the case of the kitchen scenario, that you need to go to the refrigerator, find the ham, the white cheddar cheese (because you know I like that, not American), the Djion mustard (because you know I like that on my ham sandwich and not mayo), find a loaf of bread, assemble the whole thing, put the ingredients back, figure out where the plates are, plate it, and bring it out. And if you’re super observant, you’ll note that I’m skipping a whole metric crap ton of steps, like knowing how much mustard to use, taking the plastic wrap off the cheese slice, how much ham goes into a ham sandwich, what a sandwich actually is, for that matter what “ham” actually is…
You get to skip exactly zero of those minute tiny steps in writing a computer program. If you fail to fully specify any of the seemingly microscopically small steps that are intuitively obvious to you, as a human, living in a world filled with context and nuance, the computer either does the wrong thing, or fails, or sometimes both.
As a non-programmer, you’re probably telling the programmers that you’re working with to do things like “can you make that window bigger?” or “address the user by their first name” or “let the user post that on their Facebook page” or something similarly vague, in context of vast array of things of which the computer “knows” nothing.
It’s intuitive to you, and it seems simple enough… so what’s the problem?
The issue is that the programmers tasked with this have multiple layers of complexity to deal with. These days, they most certainly didn’t write all the code themselves — they used a library (chunks of code made by someone else, to solve common problems, usually for free) provided by some third party for nearly all the heavy lifting. Typically, that involves more than one library, as there are all sorts of dependencies and interdependencies.
So when you say “let them post on Facebook”, you have to realize that they’re going to look at your request and think “oh, sure, that’s easy, probably — I’ve got the data in this database here, I think we’ve got their Facebook info in a database over there, I think that we’ve got the right libraries for that, yeah, should be easy”, which leads to a fairly optimistic estimate as to how long it’s going to take.
Only to discover that when they get into it, one or more of the assumptions were wrong, or that to use the library that they need to use means that they can’t use the version of some other library that they’re using, which means that they need to upgrade to the now-current version, which means re-writing everything else in the code that uses that library (none of which has anything at all to do with your request, mind you) and then tackle the task at hand, or they discover that something they thought they could use is now deprecated and they now need to go find some other library which then has to be weighed against everything else they’re using for compatibility…
You can see how this explodes in complexity, as soon as a core assumption is found to be wrong. Going in, the assumptions seem well founded and reasonable, but when you get in there, not so much — and you can’t know, until you try.
The very best programmers that I’ve worked with start off their time estimates with disclaimers like “assuming X, then…” or “absent something not working as documented….” or the like. They know, from experience, that there is always something lying wait under the water, like a polar bear waiting for them, the unsuspecting seal, to devour. And they prep their “customer” for that inevitability.
Less experienced programmers, full of confidence in their abilities to both perform and fully understand all that needs to be done, are less cautious, and offer “yeah, sure, that’ll take about a week”. Sometimes, they’re fudging, and have enough extra time in their budget to accommodate the unexpected; sometimes, they don’t.
In that vein, the “can’t be done’ is worth considering. In software, truly, nearly anything can be done. So on it’s face, that’s nearly always wrong, unless you’re asking for a solution to a known intractable problem.
So, some translation is in order. When a programmer says “can’t be done”, it nearly always means “there’s no way to do that given what I understand intuitively as the actual operating constraints that I have to deal with working here, and it’s so hard to explain all of that to you that my head is going to explode. Go. Away.”
If you get a lot of “can’t be done”, it’s time to re-evaluate not only your expectations, but the environment in which your programmers are working. There are not enough of them, they don’t have the right resources, you’re pushing too hard on things that keep them from making core progress on real issues — something is amiss.
Instead of frustration, and disbelief, approach this with “OK, what would make it possible to do this thing?”. You’ll get a lot further, and hopefully have the chance to fix the fractious nature of what’s brewing.