Sam Gentle.com

Stateful thinking

One of the hardest things for non-programmers to learn about programming is state. That is, the surrounding context that changes the meaning of what's in front of you. In the expression "x + 1", the meaning of 1 is obvious, but the x is state; you cannot know the value of x + 1 without finding out what x is. If the value of x is defined just before, it's not so bad, but what if x is defined a thousand lines of code away? And changes over time? And is defined in terms of other things that also change over time?

It might be more accurate to say that what is hard is simulating a computer. When a programmer reads through a program, they execute it in their own head. The more complex the program, the more difficult this is, but your internal computer also gets more sophisticated as you go along. Instead of reading one symbol at a time, you start to read whole blocks of code at a time, the same way proficient readers will scan whole sentences rather than individual letters or words. However, that only makes the immediate behaviour easier to read. The amount of state you can simulate is still limited by your own working memory, and it's very limited.

Perhaps a good analogy is how your operating system deals with your keyboard. Any time you press a key it gets sent to the current application, the one that is said to have "focus". So which key you pressed is the input, and the focus is the state. The same key in a different application does a totally different thing. Luckily, the focus state is visible; the active application is highlighted so you know where your keys will go. Most programming has invisible state, which is more like using your computer without looking at the screen. In theory you can figure out what will happen with every new key you press, but over time you're going to lose track of what's going on.

It's for this reason that you often try to avoid state in software development. However, it's not possible to avoid it completely. Even if you can use a (comparatively rare) programming language with no state, there are bits of state when your application interacts with the real world. Is it writing data to a disk? Communicating over a network? Operating on a computer with other applications? State state state. It's inescapable. So we must learn to simulate state, something that it would appear does not come at all naturally to us.

Interestingly, people have emotional state that behaves a lot like state in programming. The same events, words or actions can have wildly different consequences depending on someone's emotional state. A lesson we must learn early on is to simulate that state in others so that we don't end up totally surprised by people's crazy actions. Fortunately, emotional state is fairly visible, and our brain is particularly specialised for mirroring the emotional state of those around us. That said, people still manage to make a hash of it fairly frequently. It's interesting to wonder how well we would do without those benefits.

One area where we don't seem to get as much help is with ourselves; our own future states are not terribly visible to us, and we don't seem to have the same optimisations for future states as we do for present ones. The results should be fairly obvious: we are very bad at predicting our stateful behaviour. Not only do we have trouble predicting our future state, we also mis-predict our actions even assuming a given state. No wonder planning for the future is hard!

I think that stateful thinking can be a real advantage here. Once you learn that you can't just naively assume "x + 1" will mean the same thing everywhere, you start paying a lot more attention to the x. But for stateful thinking to be useful you need two things. Firstly, you need to learn how to reason about and simulate state. Secondly, you need to actually accept that you have state, and that your future actions can't be predicted without it.