|Cinnamon Tree by Peter Nijenhuis ⁱ|
a) return the carton to where you found it in the fridge
b) return the carton to any free space in the fridge
c) leave the carton on the kitchen table
It doesn't matter that you know how to reverse a linked list; any answer other than "a" suggests you aren't a very good programmer.
Details matter, and symmetry helps you manage them. Return the milk to where you found it. Close files you have opened. Free memory you have allocated.
During a talk about Java, memory management, and garbage collection, one speaker (I can't recall his name) explained why Java wouldn't be suitable for embedded systems. Feigning a heart attack, he clutched his chest and collapsed onto the podium. Moments later, he raised his hand, saying "I'm okay, I'm okay. It's just my pacemaker doing garbage collection."
C has no such limitation, and simply stated, for every malloc(), there should be a free(). There are situations though, that distort the symmetry, such as strdup() which allocates memory for a duplicate string. Treat that like a malloc(), and you'll be fine. Sometimes error handling might force you to depart from an execution path prematurely, and thus accidentally bypass a free(). In that case, you would need to remember to code another free() or risk a memory leak.
In C++, Stroustrup and Koenig address these issues with resource acquisition is initialization, or RAII. RAII, a term coined by Stroustrup, uses the symmetry of constructors and destructors to allocate and free resources on stack based items. Once an object goes out of scope, its destructor is called which frees any acquired resources, such as memory, file handles, and mutexes.
Clearly, symmetry is practical and beautiful, and goes beyond computer science. It can be seen in biology (decoding DNA), chemistry (the shape of benzene), and physics (quantum mechanics). Symmetry is also apparent in the arts, fashion, and story telling. And here we have Java, and more recently, Rust, trying to take some part of that away. The argument is that by handling these gritty details, the programmer is free to focus on understanding the problem and coding the solution. But that misses the point that the practice of using symmetry to solve problems is invaluable.
I don't begrudge a language trying to protect me against common mistakes such as memory leaks and buffer overruns, but realize these problems are overstated, and can be effectively managed by programmers who aren't necessarily more intelligent, but by those who just care more deeply.
Returning to the milk example above, Suze Orman, a financial advisor, uses a similar observation to gauge a client's financial life:
Cars are another dead giveaway. I once knew a woman who had serious external power and a super-impressive career. But her car was a disgusting mess: fast food wrappers all over the place and a trunk that was a mini-dump. One day she was driving us somewhere and asked me to pull her wallet out of her purse; my hand came back smeared in lipstick. Ick. No surprise, her financial life was a mess, too.
If you are plagued with memory leaks and buffer overruns, no language is going to make you a better programmer. But thinking about symmetry just might.
1- licensed under Creative Commons BU-NC-ND 2.0