When you run into a problem, a bug in your code, how do you try to fix it?
Do you try to debug the problem, in order to figure out what the root cause is? Do you use tools like debuggers, loggers or code inspections, in order to better understand where and what is causing the problem, and then carefully analyze the best way to fix it?
Or do you make random changes to random parts of your code, see if that fixes anything, and repeat the above loop over and over again until things start working?
I like to call the latter approach “Evolutionary Programming”. Comparing this style of programming to evolution is probably giving it too much credit, but it’s actually a pretty apt analogy. Evolution, through random mutation and natural selection, is the polar opposite of Intelligent Design. Evolution has no sense of analysis, design or intelligence. It simply mutates random portions of your code (DNA), keeps the changes that “made things better,” discards the rest, and keeps looping through this forever until it gets to something successful.
Such an evolutionary approach is already being used in specific subdomains, such as Machine Learning and AI development. Maybe one day, someone will figure out how to make the evolutionary approach work in mainstream Java programming as well. However, that day is certainly not today. If you’re a programmer and your personal approach to fixing bugs is to rely on the Evolutionary Method, don’t. You’re doing something very very wrong.
“But evolution works” you may argue. “If it can produce something as complex as human beings, why not use that same method in my daily programming?” Well, consider this:
- It took evolution a billion years to accomplish what software developers were able to accomplish in decades. That’s a 10000000x difference in development velocity.
- The end-product of evolution is something so complex, that no human mind can understand it. Consider the millenia that men have spent studying biology & medicine, and we’ve only just started to scratch the surface in the past century.
- The systems produced by evolution are so interconnected and tightly coupled, that it’s impossible to fix one problem with introducing 100 others. If you need proof of this, look at the list of side-effects that accompany any medical drug.
I bring up this topic, because I just witnessed it first hand during an interview with an undoubtedly bright candidate. After 40 minutes of building a complex data-structure, it came time to test his creation. He knocked a few easy bugs out of the way in the first few iterations, but hit a brick wall on a more complicated bug.
Instead of digging deeper into the code in order to understand what it was doing, or using the debug tools in order to narrow down the specific code-block which was showing buggy behavior, he decided to fork off an evolutionary branch. He started mutating random parts of his code, and rerunning, just to see if that somehow fixed things. After 15 minutes without any progress whatsoever, he gave up and was even more confused than when he started.
A short while later, when trying to debug his code myself, I realized that he actually had a typo in his test-input. Turns out his code was right all along. But by focusing all his efforts on fixing a non-existent bug, instead of trying to understand the real cause of the error, he ended up getting further and further away from the solution with each step.
If you’re somebody with no aptitude whatsoever for analyzing systems, the evolutionary approach might be your best remaining option. But if your intellectual capacity is indeed lacking so significantly, you really should reconsider your career choice. A different profession, such as politics, might be more up your alley. Maybe one day, someone will build an AI that is capable of developing software using an evolutionary approach. Such a system may actually be successful, because computers can be massively scaled out and parallelized. Unfortunately, the same cannot be said of your labor.
The next time you hit a problem, don’t just make random changes until something somehow starts working. Such an approach may work in the ultra-short-term, but it’s only going to produce spaghetti code that no one else will be able to understand, reuse or improve upon. You’re not a force of nature, nor are you a robot. Leave evolution to the science textbooks and start practicing some intelligent design.