In programming there is a problem known as circular dependency, which you know is real because it has its own Wikipedia page and everything. In summary the problem is that Class A needs to know about Class B, but Class B needs to know about Class A. The problem arises because the compiler has to pick one to start with.
As an analogy let’s take Bob and Alice who have been married for many years and won’t go anywhere without each other. Strolling through the park they find the bridge across a stream is out but they are in luck, someone with a two seater swan boat is willing to offer rides. Since it is his boat (and no one is going to question why in the world he owns one personally) he must remain in it at all times.
Now since Bob and Alice, or Alice and Bob if you prefer, won’t go anywhere alone here is the problem. The Cygnus captain only has room for one. He points to Alice and says “I’ll take you across first” to which she responds “But Bob won’t be on the other side when I get there so I can’t.” He turns to Bob and says ” if you go first then you will be on the other size and therefore she can cross right after.” Bob replies “That sounds great but only if Alice meets me across the river when I get there.” Exasperated, holding his face in his hands, the captain doesn’t see the iceberg coming downstream which proceeds to sink his swan. Luckily the river is only a few feet deep but still he winds up wet and boat-less.
He hit an impass, there is no way to get one to cross without the other being there first. Despite The Substitute teaching otherwise, sometimes the best solution is not to throw a boombox out a second story window. Outside of programming this is known as the chicken or the egg problem. Clearly one came first but there is no clear cut answer as to which is correct (the egg is the right answer btw).
Why am I talking about eggs?
Other than the fact that they are delicious, this problem comes up ALL THE TIME. Just today I was listening to a cross discipline engineering project where the hardware people said they couldn’t finish without the software (true) but the software people couldn’t get started without the hardware it runs on (also true). Think back and it shouldn’t take too long to come up with similar situations in your life. Businesses (especially tech support) thrive on this.
“To recover your pin number, please type in your pin on the phone keypad now.” Most cases aren’t this bad but stuff that stupid does come up now and again. Sadly the people involved are likely alive and employed.
How do we fix this?
You’ve convinced me I hear you saying, now how do I solve these seemingly insurmountable cycles? First I say: Get out of my house! Secondly we have to take a look and see if we really need one before the other, if not hooray the problem just fixed itself. The key to break the cycle is to do anything that breaks the cycle. In the world of making things that depend on other things this would be a prototype.
Wait, did you say hardware Prototype?
Not exactly, you filthy word injector, but yes that is what was implied. Certain situations make prototypes more than helpful, they become essential. That situation would be any time you don’t know how to do something. Since any interesting project will have at least some unknown aspect this covers 99.9999+% of all products. People thought all vacuums were the same until James Dyson got tired of clogged filters and did something about it.
The way to break the cycle is to build something, anything that gets you closer to the goal. IT WILL BE WRONG and that is okay. Failing when you absolutely, 100% upfront intend to fail isn’t bad, it’s only bad if you don’t learn from the experience.
Say you are building a widget; I’ll wait until you finish speaking to continue.
This widget is revolutionary and will sell like hotcakes back when people used to buy a lot of hotcakes. The only problem is like many products it requires hardware and software. Damn, now we are really screwed because apparently programmers and engineers (not software engineers) have a fundamental mental disconnect in how they approach problems.
The Hardware Engineer Says:
I have to design this perfectly up front, it is too expensive otherwise. If I miss one detail it will take months to get the manufacturer to retool the assembly line, that will costs tons of money, hell it may kill the entire project. Better take as much time as it takes to get it right the first time. Wish that lazy Programmer would tell me the specifics he needs, then I could spec just enough power to make it work.
The Programmer Says:
I have never done anything like this before, there is no way I can get it right the first try. Would love to make a quick prototype that supports the most important features of the product but the hardware to run it doesn’t exist yet. What the hell is wrong with that Engineer wasting time on crap that will clearly be wrong the first time, if not multiple times?
Who’s right?
As one of my professor’s says “it depends,” which is sadly almost always the correct answer for a complex situation. Both the Engineer and Programmer raise good points. It does cost money to make mistakes but it is hubris to assume that by working really really hard you can get it perfect the first time. In the computer world contradictions this strong cause your compiler to lock up, machine to blue screen (even on Linux), and the cpu to burn itself to ash to avoid the agony. The real world, however, thrives on this shit. Those familiar with quantum weirdness know that Schrödinger’s cat is both alive and dead at the same time, at least until you open the box. Chickens and eggs don’t care which one came first, they just keep doing whatever it is they do (being delicious).
That wasn’t an answer at all!
Damn, you caught me. So here is my opinion on how you solve the problem. In building our widget you get the engineer to create a really cheap prototype that does the absolute essentials probably right. But it is cheap and fast. He then gives this to the programmer who can start prototyping while the engineer works on fixing obvious and not so obvious design flaws. You know, the kind that make you slap your head and say “wow, wish I had known about that back in the design phase.” The really important part is that they share feedback throughout the product life cycle. If the engineer flings a circuit board over the wall then bit later a CD comes bouncing back it absolutely won’t work. Close feedback is the key to making this work. Note: you can have good feedback without being able to physically talk face to face, these days this thing called the internet solves those kinds of problems. In the software world this form of management is called Agile Development. In the engineering world it is called Blasphemy.
So we are starting out this supposed year long project. Team A is using the old standby methods to build, Team B is trying out new, more radical thinking. Suppose the deadline is absolute. There is no reasoning with it, no extending it, no nothing. Here is how these projects work out often enough. Numbers may or may not be accurate, but they prove my point.
Date | Traditional Engineer | Traditional Programmer | Agile Engineer | Agile Programmer |
---|---|---|---|---|
Month 1 | Got lots of research to do! | Lots of research to do! | Finishing touches built on first prototype after week one brainstorming session. | Been working with engineer to get prototype working. |
Month 3 | Moved on to designing boards and actual engineering. | Toyed around with a few ideas but not really sure what the hardware will be so can't write anything. | Got lots of feedback from first prototype, started on next, more polished one. | Got a pretty good idea where the hard parts are going to be, creating software prototypes of tough stuff. |
Month 6 (of 12) | Design 90% done but still a few kinks to work out. | Playing solitaire as there is no real work to be done until have some device to test out. | Last prototype nailed it, now polishing design and adding optional features. | Testing of required features mostly done, minor bugs remain. |
Month 8 | 90% done. | Trying to look busy. | Final polish being added. | Minor features being coded. |
Month 10 | Done with board, passed off to programmers. | Coding franticly. | More final polish, working with marketing to improve product launch. | Optimizing code and working on documentation. |
Month 11 | Waiting on feedback from lazy programmers. | Code harder than first expected, putting in extra hours. | Started work on new project while waiting for launch. | Final cleanup and ready for release. |
Month 12 | Yelling at programmers to get done. | FUUUUUUUUUUCK! | Enjoying work on second product while success of first happens. | Started on code for second product, not burned out from first project. |
Yes this is an extreme exaggeration, but it’s my blog so tough crap. And many real world products move along exactly the same way as the first team.
Summary
If you want to break the chain of impossible dependencies you have to do something! Planning gets you no closer to shipping when you cover the same ground over and over and over again. Take a chance and build something that might work, or might not. As long as you aren’t making life critical products (like a pacemaker) this is not only a good way to go, but in my opinion it is the best way. Look for future posts on how waterfall design methods (that all engineers use) are crap and agile hardware development.
Recent Comments