I'm James Hague, a recovering programmer who has been designing video games since the 1980s. This is Why You Spent All that Time Learning to Program and The Pure Tech Side is the Dark Side are good places to start.
Where are the comments?
Turning Your Code Inside Out
If I gave this assignment to a class of novice programmers:
Write a C program to sum the elements of an array and display the results. Include five test cases.
I'd expect multiple people would come up with a function like this:
There's a cute new programmer-ism in that solution: displaying the output is built into
sum_array instead of returning the sum and printing it elsewhere. Really, it's hard to see why that one extra line is a bad idea, at least up front. It prevents duplication of the
printf call, which is good, right? But tack on an extra requirement such as "Use your array summing function to compute the total sum of three arrays," and there will be an "Ohhhhh, I don't want that print in there" moment.
The design error was obvious in this example, but it crops up in other cases where it isn't so immediately clear.
Let's say we're writing a video game and there's a function to spawn an attacker. To alert the player of the incoming danger, there's a sound accompanying the appearance of each new attacker, so it makes sense to play that sound inside
Now suppose we want to spawn five attackers at the same time by calling
new_attacker in a loop. Five attackers are created as expected, but now five identical sounds are starting during the same frame. Those five sounds will be perfectly overlaid on top of each other, at best sounding five times louder than normal and at worst breaking-up because the audio levels are too high. As a bonus, we're taking up five audio channels so the player can hear this mess.
The solution is conceptually the same as the
sum_array example: take the sound playing out of
new_attacker and let the caller handle it. Now there's a single function call to start a sound followed by a loop that creates the attackers.
Why am I bothering to talk about this?
This method of turning your code inside out is the secret to solving what appear to be hopelessly state-oriented problems in a purely functional style. Push the statefulness to a higher level and let the caller worry about it. Keep doing that as much as you can, and you'll end up with the bulk of the code being purely functional.
(If you liked this, you might enjoy Purely Functional Retrogames.)