But I've also been thinking about physical analogies, and that got me thinking about relativity as applied to language semantics. A forward analysis of a language with a given semantics should be equivalent to a backward analysis of a "dual" language with the operators swapped (subtracting instead of adding, dividing instead of multiplying, etc.).
Now, of course, that doesn't occur in practice, because we throw away a lot of information in the course of evaluating a program - literally dissipating it as heat and electricity. But what if we consider those outputs as part of the program?
Suppose that we augment our microprocessor with a tape where we output every value discarded - the values of each register overwritten and each overflowed bit. If we read that tape in reverse, now we can run the language backward - with the "dual" instructions reading the values when needed!
So let's go back to the physics analogy: the information in our program is like a set of particles, and the instructions are interactions and decays of those particles. Discarding information (e.g. by overwriting a register) emits a particle, and synthesizing information (e.g. by reading from a port or an immediate value) absorbs one. Now we can apply our relativistic reasoning, and we find that - with the addition of our absorption and emission traces! - forward and backward analysis are actually the same.
Interestingly, I believe that the "particles" here are more or less real - overwriting registers causes actual physical effects such as voltage drops on supply lines and emission of thermal photons. It's a nice physical basis for linear logic.