Wednesday, September 19, 2012

Insights from John Carmack on Static Analysis

Insights from John Carmack on Static Analysis

So here it goes, some observations I would like to make having to deal with John Carmacks article on static analysis.  I feel a couple insights he sharing have broader consequences that the general programming world hasn't ever 'internalized'.

Failure of communication, assumptions:
A lot of the serious reported errors are due to modifications of code long after it was written. An incredibly common error pattern is to have some perfectly good code that checks for NULL before doing an operation, but a later code modification changes it so that the pointer is used again without checking. Examined in isolation, this is a comment on code path complexity, but when you look back at the history, it is clear that it was more a failure to communicate preconditions clearly to the programmer modifying the code.

 The quoted paragraph above from Carmack and the lines I've highlighted are something I have seen over and over again.  Programmers often assume that they do not need to comment the 'intent' or 'preconditions' of their code.  As a block of code or a class, or even a class method grows in complexity the variables being interacted with require more context to understand.  The more the code the more context needs to be understood before a change can be made. 

Your job as a programmer is to organize the code so no matter what portion of it is being edited the context of the code is as inherently visible and logical as possible.


Code Maintainability

As more people touch a code base the need for good and robust communication between developers becomes imperative.  Developers must recognize that sharing the 'intent' of the code with eachother is paramount.  If you are developing a character animation system you must explain to us what problem you are solving.  A method called 'ik_constrain_jt( jt, v )
With a comment "Constrain's joint by vertex and joint"  is simply not sufficient.  What does your code do, how should it be used, and how does it fit into the system as a whole?

Most developers are very ambitious and all too willing to hunt down endless lines of code.  They have become accustomed to spending hours tirelessly running down a call hierarchy. The need to do this has become all too common from large poorly documented systems that we as developers have had to deal with a large portion of our professional lives.
I ask the development community at large to take not of this time and energy you pour into understanding the behavior of code, or re-understanding each time you deal with it.  Elegant design lacks complexity, and behaves consistently.  Elegance is probably the hardest of all features of code to achieve. It requires discipline in design and a clear vision for the desired product.   The tipping point happens when you devote more time to understanding code structure and execution path than you do programming.  Refactoring or redesign or cleanup is needed at this point.  I find many developers are in abusive relationships with their code bases and they don't even realize it.  The code base batters the creative energy from them and impedes progress and yet all seems normal to them.  We can't assume code will always be easy to understand, we can't assume that the use case or the person using our code will be familiar with why it's performing the function it is.  And we can't assume that we will be the only ones maintaining it.

You can find John Carmacks' original article here