Complex Systems are Bad

If it weren't obvious from the title, I am heavily biased in favor of elegant solutions to problems. So much so, that I've been known to not actually solve a problem if I can't find “The Book's” solution. I cannot state strongly enough that this is stupid of me, and I'm trying to fix this foible of my personality. That being said, just because I'm stupid, doesn't mean I'm wrong.

I was recently moved to take up SDL programming again. My desire had fizzled out before for lack of an application, but I now had an idea I wanted to try out. I went to Lazy Foo' because in general those tutorials are pretty good. The first thing you need when programming with SDL is to set up your programming environment, which Lazy Foo' has a variety of options for. When I was following the tutorials on my previous computer, I had used the command line methods because they suit my bias against complex systems. I wanted to give an IDE a chance this time, because I keep hearing they can improve productivity.

I started with the tutorial for setting up Code::Blocks (12.11), and installed it (noting that its current version is somewhere in the low 20s). I followed all the steps as Lazy Foo' laid them out, but I was running into a problem. The program would not compile, and looking at the console output “ld.exe cannot find -lSDL2main, ld.exe cannot find -lSDL2”,  corresponded to one of Lazy Foo''s typical scenarios. In the words of Step 5, “If you get an error where the linker complains it can't find -lSDL2 or -lSDL2main, it means you messed up this step”.  Well, no, I did not mess up that step, but presuming I did caused me waste my time double- and triple-checking everything.

Looking at the build log (or similar tab in Code::Blocks, I can't remember since I've removed it from my computer) I saw that the linker was finding and immediately skipping over my “incompatible” versions of the SDL files. A bit of searching showed that it was probably because I was using the 32-bit versions of the files, as per Lazy Foo''s instructions. So I tried a little experiment, I swapped out the 32-bit versions for the 64-bit versions and, wouldn't you know it, Code::Blocks compiled without complaint. Turns out, just telling people they messed up a step is not adequate pedagogy.

This was not the end of my worries, for just because a program compiles doesn't mean it will run. As soon as I ran the executable, I received an error dialog, something like “Error exit status: [extremely large negative number]”.  Back to searching, this time I found the exact error message, and Microsoft Support's response was to install updates. I looked, and it turned out there were updates to install. I installed them and restarted my computer, re-compiled, and… received the same error dialog as before.

At this point I was tired of tried-and-false, and decided to revert to tried-and-true. I uninstalled Code::Blocks, manually installed MinGW, and manually compiled the program. This executable ran without problem, and I was able to move forward after wasting an hour on “productivity enhancing” systems.

There are numerous possibilities to why this was a problem. It could be that Code::Blocks has introduced a bug in the 8+ versions since Lazy Foo' wrote the tutorial. The problem could be with the tutorial itself. It could be with the SDL files, which are also different versions from what Lazy Foo' was using. It could be that Microsoft has changed something, or my processer is different. It could be that the whole thing only used to work in the first place because of some undefined behavior. It is a complex system, and controlling for these different variables would be highly expensive in time and money. Trying to solve the complex problem was not worth the itch I'd be scratching. Instead I went back to the simple solution, and was rewarded not just by a functioning executable, but also by a more-complete knowledge of what was going on under the hood.

On the other hand, sometimes when I aim to scratch an itch I boil it down to the simplicity of, “just don't scratch it”.  This is the most elegant solution: realizing there is no real problem in the first place except the one I make in my mind. This would not have worked in a different situation which I will now recount.

I was living with my sister and niece in a house being fixed up. There was a stairway my brother had begun to dismantle, which my niece lacked the self-control to avoid. She wanted to go upstairs, because adults do that, but she was just recently learning to walk so stairs would have been dangerous. I designed a temporary grating, to be built elegantly with joinery and without screws, and when I was going to build it I quickly realized that craftsmanship takes time. I could have stuck to my guns, working towards the elegant solution, or I could keep my niece safe. I chose to keep my niece safe, and made a solution that was fast, dirty, and done. The thing was hideous, and when my niece grabbed onto it and shook it, I realized that the screws were ripping through the wood. I added some nails to hold it in place, which made it even less elegant, but more safe.

Sometimes the cobbled-together solution is the one you need, and the elegant solution is a luxury you can't afford. Other times the cobbled-together solution can't possibly work, because it's built on top of other cobbled-together solutions, which are cobbled-together all the way down. When it comes to computers, the latter is the usual case.