Easy to reason about is a culturally specific term, which is why it's so hard to come up with concrete examples. It is a term which is anchored to the people who are to do the reasoning.
"Easy to reason about" is actually a very self descriptive phrase. If one is looking at the code, and wants to reason what it does, it's easy =)
Okay, breaking it down. If you're looking at code, you usually want it to do something. You want to make sure that it does what you think it should do. So you develop theories on what the code should be doing, and then you reason about it to try to argue why the code does indeed work. You try to think about the code like a human (rather than like a computer) and try to rationalize arguments about what the code can do.
The worst case for "easy to reason" is when the only way to make any sense of what the code does is to go line-by-line through the code like a Turing machine for all inputs. In this case, the only way to reason anything about the code is to turn yourself into a computer and execute it in your head. These worst case examples are easily seen in obsfucated programming contests, such as these 3 lines of PERL which decrypt RSA:
As for easy to reason, again, the term is highly cultural. You have to consider:
- What skills does the reasoner have? How much experience?
- What sorts of questions might the reasoner have about the code?
- how certain does the reasoner need to be?
Each of these affects "easy to reason about" differently. Take the skills of the reasoner as an example. When I started at my company, it was recommended that I develop my scripts in MATLAB because it is "easy to reason about." Why? Well, everyone in the company knew MATLAB. If I picked a different language, it would be harder for anyone to understand me. Nevermind that MATLAB's readability is atrocious for some tasks, simply because it wasn't designed for them. Later, as my career progressed, Python became more and more popular. Suddenly MATLAB code became "hard to reason about" and Python was the language of preference for writing code that was easy to reason about.
Also consider what idoms the reader may have. If you can rely on your reader to recognize a FFT in a particular syntax, it's "easier to reason about" the code if you stick to that syntax. It lets them look at the text file as canvas that you painted a FFT onto, rather than having to get into the nitty gritty details. If you're using C++, find out how much your readers are comfortable with the
std library. How much do they like functional programming? Some of the idioms which come out of the containers libraries are very dependent on which idomatic style you prefer.
Its also important to understand what sorts of questions the reader may be interested in answering. Are your readers mostly concerned with superficial understanding of the code, or are they looking for bugs deep in the bowels?
How certain the reader has to be is actually an interesting one. In many cases, hazy reasoning is actually enough to get the product out the door. In other cases, such as FAA flight software, the reader is going to want to have ironclad reasoning. I ran into a case where I argued for using RAII for a particular task, because "You can just set it up and forget about it... it will do the right thing." I was told that I was wrong about that. Those who were going to reason on this code weren't the sort of people who "just want to forget about the details." For them, RAII was more like a hanging chad, forcing them to think about all the things that can happen when you leave scope. Those who were reading that code actually preferred explicit function calls at the end of the scope so that they could be confident that the programmer thought about it.