Carmack: Parallel Implementations
altdevblogaday.com
altdevblogaday.com
One could tangentally conclude from reading this post that a well designed architecture would easily support a second parallel implementation, whereas a heavily-coupled, poorly designed architecture would make the parallel implementation hard to pull off. Neat.
"Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function."
- John Carmack (Twitter) http://twitter.com/#!/ID_AA_Carmack/status/53512300451201024
Not "sometimes", "mosttimes"!
Here's a good series of articles about it: http://prog21.dadgum.com/23.html
Even for gameplay code, it could be nice to have explicit tracking of what the mutable state is, to prevent bugs. He has some fascinating slides about this, if you google for "The Next Mainstream Programming Language". Extensive discussion on Lambda the Ultimate here:
http://lambda-the-ultimate.org/node/1277
Definitely one of the most interesting things I've seen in a while.
In a mixed model, you can have a mutable state but still have a large bank of trustable, testable, parallelizable behaviors defined in pure or deterministic functions with well defined contracts of input and output states.
This lets them gradually test it at scale (expose the new feature to x% of their users and slowly grow x).
More details on their dev blog: http://code.flickr.com/blog/2009/12/02/flipping-out/
In the beginning, we avoided copying when we experimented by using flags; then we used source control branches to make diff "copies". In the end, we just copied.
One is basic refactoring purity. The idea is that you progress in steps such that at every step the program still works as expected and passes unit tests, implementing the classic "build replacement, switch client code, deprecate old code, remove old code" cycle.
The other is the idea of feature flags, which allow you to turn on or off various experimental code paths configurationally. This technique is especially powerful when used on high-traffic web sites (google, amazon, and facebook use it extensively). You can basically roll out new features or even backend changes slowly to a percentage of your users at a time, with the ability to roll back as necessary. It's a very powerful risk mediation tool.
I don't get this particular implementation detail. If it's not a flag, how would it be implemented?
It's not like you're coding it on two separate branches, since it needs to switched at runtime. It looks like the plea is for it to be pure functional, to make it easier to switch it in and out. But I can't quite picture how he's implementing this.
I can imagine that it allows more freedom re-working the code. You don't have to worry about breaking the original implementation this way, freeing up mental capacity.
another way he seems to have found to free mental capacity - his text is suspiciously lacking mentioning of abstractions and design patterns. Switching between implementations? There is a pattern for that!