Scientists Explain Why Computers Crash But We Don't
physorg.com
physorg.com
Cells have a type of redundancy programs do not have, and may never have, and it actually hasn't got anything to do with the source code at all. They have numerous independent copies of things that mostly work, most of the time. They perform tasks that transform lots of things into lots of other things, most of the time. The whole system is built so that everything mostly works, most of the time, usually recovers, and it doesn't matter much whether this cell dies or that mitochondria malfunctions. It's an entirely different set of primitives brought on by massive parallelism. (And not the usual biological parallelism you hear about in the brain, but physically, everywhere.)
It's the difference in primitives that brings about the difference in result. Difference in optimal layout is an effect, not a cause. Cells don't have the option to work like programs, and programs really don't have the option to work like cells. (At least not without a lot more computational resources.)
What makes you think we can't design reliable software systems that way? In fact, I think it has already proven to be a remarkably good idea: http://erlang.org/
It's still not the same. There's just no biological equivalent to a bit of code that is dividing by zero or referencing a file that doesn't exist, or any of several other errors I've made that have brought enormous swathes of the supervision tree down because they're restarting crappy code. Erlang adds this sort of biology-style robustness at the top of the stack, biology itself works with it at the bottom of the stack. That changes everything. Programming with massive unreliable parallelism may indeed someday happen, but it's a long road between here and there.
Someone I knew did a master thesis on the male reproductive system, he told me that males have 10-15 largely independent biological pathways to produce sperm. From nature's perspective the point is presumably that if you can still breathe, you should be able to reproduce :)
If we were to put the same level of effort into a file reading module, we would have the files replicated over 10-15 different systems with file reading code written by a dozen different people in a dozen different languages, all using different heuristics to locate a similar file (or a backup) if the original wasn't found. Add some sort of selection mechanism to pick the best result from the 10-15 return values, and you would have a very resilient file reader :)
I can't imagine we will ever want to write code like that by hand - drawbacks include development cost and maintenance hassle, and the system becomes very hard to understand and debug.
But it's still an interesting approach. In computer systems I suppose we could bring it about by some variant of evolutionary programming. ( http://en.wikipedia.org/wiki/Evolutionary_programming )
I could see how AI could use such a thing, especially since the best intelligence we know works that way. But in general? It seems less than awesome.
There are also examples of both (Erlang and Dynamo) combined: Riak and Cloudant. These systems run multiple Erlang processes on multiple redundant nodes. Processes or nodes can die without ill effects, and often the system knows how to heal itself.
I don't think it's the obvious, well-understood fact that biological systems have massive, redundant parallelism, whereas our software systems do not.
I believe it in fact says something very specific and fairly non-intuitive: that biological systems have many slightly different copies of key routines, whereas our software systems as they are designed today do not.
"That’s why E. coli cannot afford generic components and has preserved an organization with highly specialized modules, said Gerstein, adding that over billions of years of evolution, such an organization has proven robust, protecting the organism from random damaging mutations."
For example, imagine instead of having one 'sort' function, you had different sort functions dispersed throughout every area of your code that performs sorting, and each one was very slightly optimized (through design or some unspecified evolutionary process) for the particular characteristics of the data being sorted at that program location.
Thus, 'sort' is no longer a single point of failure. If one of your sort routines has an exploitable buffer overflow, then it's probably the only one that does, which limits the potential damage to the system as a whole -- especially if you've designed your entire system this way.
Could it be better in some cases to copy and slightly modify a software component, than to simply reuse it?
In evolution, you're pretty much guaranteed a breakage at some point that can't be fixed. That's not quite as true with software - you're still guaranteed breakages, but you get to fix them, and fixing dependent systems is a whole lot more economical.
I think the best analogy is interfaces. You code to an interface with multiple implementations, and if a problem occurs, you switch implementations. Next, if you have vulnerable and complex components, you make sure they each have a custom implementation, so the inevitable bugs can't be widely exploited.
It's unfair to criticise a system for having a failure-state, because all systems have failure states. Different systems have different ways of handling failure-states, though, and the brain's ability to cope with failures is nigh amazing.
If you start dialing a number, and somebody calls your name and you turn around and talk to them for 10 seconds, you probably can't resume where you left off, either. :)
It seems to me though that there is a big difference in the problem domains. Biological systems can produce a range of outputs that are on a sliding scale of more or less desirable - but software systems are generally specified to produce a single correct output, and any deviation from that is regarded as a complete failure.
Bull. There are two reasons why the shapes are different.
1. The bottom of the Linux graph is smaller because there are not very many primitive operations on a computer. Data is homogenous. There are 256 interchangeable values for a byte. By comparison, a bacterium has to use separate pieces of machinery to handle chemicals made up of the dozens of non-interchangeable elements that it works with. On a computer, you might use one single function for searching binary search trees all over the place in different systems, regardless of the data. In a bacterium, when code gets copied, the copy is modified. Every new application is a fork of some other application, welcome to a developer's nightmare (a good argument against ID... a designer would never duplicate so much code). Developers reuse code because they can, bacteria doesn't reuse code because it can't.
2. The top of the Linux graph is larger because computers have to do more. Computers get selected for features. Bacteria get selected for survival. The bacteria have to "just work", whereas people expect to be able to configure computers. I can plug 100 different network cards into my computer, but don't expect to plug a different flagellum into a bacterium. Maybe it's just a matter of level, if you picked a higher point in the call graph eventually you'd get to "main", no?
My take away: If there is an intelligent designer, they'd be an awful programmer.
I have always been amazed in how the unix approach of cobbling bits together is often more reliable., than trying to write one large program.
True, but it also makes it neigh impossible to make any changes to the system, which is generally a desirable trait in software.