The before/after delta is very satisfying and clearly easier to work with. Very nice.
How does the DSL handle side effects? I'm assuming any term here could be a compound expression, so what part of the system prevents "0*callfn()" from reducing to "0"?