A Lesson From Nature: Complexity from Simplicity
I recently came across a video showing an “Amazing Crabs Shell Exchange” and realized that it was a perfect example from nature of how seemingly complex (or “amazing”) behavior can emerge from simple governing desires. This is directly applicable to programming.
Before I explain what I mean, I encourage you to watch the video.
It‘s undeniable that the video shows an amazing phenomenon, but if we take a moment to think about it, the crabs‘ behavior doesn‘t have to be as sophisticated as it seems.
For a line to form like that, there doesn‘t need to be any instinct or intelligence that specifically wants to form a line. It only requires that each crab want to find a new shell slightly bigger than their current one. Naturally, each crab will want to stay close to the shell that they desire. If a better one comes along, they will certainly switch to that one. With those simple instincts, a seemingly sophisticated line forms.
So what does this have to do with programming? Well, the same kind of sophistication emerges from simple algorithms. We can take Insertion Sort as a simple example. In order to do something sophisticated (sort a completely unsorted list), we only need to know how to insert an element properly into an already sorted list. Repeating that simple task over the entire list of original elements, we come out with the sorted list.
However, there‘s a big difference between these examples and the actual task of programming. When we develop code, we work in reverse. We start with a complex problem and we need to break it down in a way that lets us implement the simplest solution possible.
This is a lesson especially important to new programmers, but even experienced programmers need to be reminded of this periodically. The hard work of programming happens before you ever write a line of code. When approaching a problem follow these steps:
- Fully understand the problem – Think not only about the obvious aspects but also the edge cases. We will still probably miss some complications until we start implementing it, but taking time to understand the problem will help us come up with a simpler solution.
- Explore different mindsets – Now that you have a good grasp of the problem, experiment with different ways to look at it. One might initially attack the crab shell exchange problem in terms of how to organize many crabs at once like a god, but it will probably help to also look at it from the perspective of a single crab.
- Sketch it out – It‘s often extremely helpful to map out your possible solutions in a visual way. It is much faster than implementing it in code and helps you wrap your mind around the details of the solution which will help you organize your code better later.
- Codify it – Both in the literal and figurative sense of the word. Yes, we are finally writing code at this point, but that code is simply our way to express the solution we‘ve already carefully considered.
- Evaluate it – An important aspect of evaluating it is simply ensuring it functions correctly, but don‘t forget to also look at how well you broke down the problem in the first place. In extreme cases you might actually reimplement it after realizing a much simpler way to address the problem, but most of the time, you will just take lessons forward to the next problem you need to tackle.
Programmers don‘t just write code, they‘re problem solvers that codify solutions.