Arch-Engineer
When dirty is better than pure
Software Design Tip: Weak Purity
Let's talk about purity. Pure code has no side effects. Purifying your code is like eating vegetables: it makes it parallelizable, reusable, testable, modular, and helps prevent 9 forms of cancer. Also like eating vegetables, it makes your program use a lot more space.
As you can see, I'm no purist about purity, and prefer my design discussions to resemble engineering meetings rather than religious sermons. You can also get a lot of these benefits from something called weak purity, according to Simon Arneaud. A weakly pure function can mutate its arguments or their members, and can read from global state, but can't write to global state. This helps with testability, readability, and modularity. Read his blog post to find out how.
One benefit he doesn't discuss is with temporal coupling. Temporal coupling is when the order of function calls matters, as in:
…
stop_the_car();
The relation of these two function calls is obvious here, but that stop_the_car() may be several pages down in a big block of code commented "Shut down transportation network," which, to the junior programmer, is just begging to be split into a shutDownTransportationNetwork method. Next thing you know the two calls are seven layers apart, and no intervening code can be removed safely.
Here's how it looks as a weakly-pure function:
…
stop_the_car(&car);
Now it's clear that these two functions influence each other. There's a data flow dependency of the second invocation on the first. No-one's about to separate these without a second thought, and, if they do, it will be plain as day what's relevant and what's not.
One of the criteria for good code is that all temporal constraints are evident in the data flow dependencies. You can do this by making functions weakly pure.
If messing up the order of methods is really bad, you can use static types to help enforce the order: make start_the_car return an object of a special type which is required by stop_the_car. If you want to perfectly enforce the ordering, get a language with typestate.
Research Corner: Storyboard Programming
One of my officemates graduated this week. His work is super cool (he's using a program synthesizer to optimize itself), but I don't have any useful software engineering lessons to draw from it, unless your software is a SAT solver. Instead, I'll talk about his brother's research.

The Storyboard Programming Tool turns whiteboard diagrams into code. Literally. Here's the video. (Your job is safe; it only does data structures.)
To do this, it needs three inputs: input/output examples, a description of the data structure, and, for technical reasons, how many while-loops to use. There are a lot of lessons here, from how the examples needed follow from the shape of the data structure, to why the code in such a function can be constructed from very limited building blocks. I want to focus on the bigger picture: those three (really, two) things contain all the information.
One mistake I've seen even in relatively advanced programmers is to try to understand a program by…reading the code. Give them a red-black tree, and they'll start reading the code. Give them a GUI framework, and they'll start reading the code. When I ask them to design a program to play Minesweeper, they start writing the code. After they learn how to think in terms of data structures and invariants and postconditions, seeing the code becomes as interesting as asking your coworker every turn he takes to get to work, when you already know where he lives.
One of the greatest gifts of program synthesizers is that they show us which parts of programming are creative, and which are mechanical. Code is details. Data structures are design.