His insight was that x = x + 1 isn't contradictory once you recognize that the two x's have implicit temporal subscripts. That is, "the value of x at time t+1 = the value of x at time t, plus 1". Make that temporal dimension explicit in the language and you can go back to having a nice equational semantics.
It's interesting, though, and perhaps germane to your point, that this insight turned out to lead far away from mainstream languages.
I've come to the conclusion that math and programming are very different things because math isn't executable. Programs have to run on a physical machine, math doesn't. The "physical" part changes everything. As someone pointed out in a blog post recently, even programs written in the purest most side-effect-free languages have side-effects when they run. I suspect that functional programming ultimately runs aground on this discrepancy - i.e. on the intrinsic imperativeness of the machine. The "x = x+1" paradox can be seen as a distillation of this imperativeness.
Perhaps we should teach programming not as math but as a kind of mechanics.
Bill Wadge invented the dataflow language Lucid in the early 1970s by pondering this very paradox. He wrote a nice series of blog posts about it that begins at http://billwadge.wordpress.com/2011/03/23/lucid-the-origins.
His insight was that x = x + 1 isn't contradictory once you recognize that the two x's have implicit temporal subscripts. That is, "the value of x at time t+1 = the value of x at time t, plus 1". Make that temporal dimension explicit in the language and you can go back to having a nice equational semantics.
It's interesting, though, and perhaps germane to your point, that this insight turned out to lead far away from mainstream languages.
I've come to the conclusion that math and programming are very different things because math isn't executable. Programs have to run on a physical machine, math doesn't. The "physical" part changes everything. As someone pointed out in a blog post recently, even programs written in the purest most side-effect-free languages have side-effects when they run. I suspect that functional programming ultimately runs aground on this discrepancy - i.e. on the intrinsic imperativeness of the machine. The "x = x+1" paradox can be seen as a distillation of this imperativeness.
Perhaps we should teach programming not as math but as a kind of mechanics.