Debug.Trace.trace interrupts referential transparency.
An expression such as let x = e in x+x , through referential transparency, should be equivalent to e+e , regardless of what e .
but
let x = trace "x computed!" 12 in x+x
will (probably) print a debug message once, and
trace "x computed!" 12 + trace "x computed!" 12
will (probably) print a debug message twice. It should not be.
The only pragmatic way out of this is to consider the conclusion as "a side effect on which we should not depend." We already do this in pure code: we ignore the observed “side effects”, such as elapsed time, used space, consumed energy. Pragmatically, we should not rely on an expression to consume exactly 1324 bytes during the evaluation, and write code that breaks after the new compiler can optimize this more and save 2 more bytes. Similarly, production code should never rely on trace messages.
(Above, I write "probably" since this is what I think GHC is doing at the moment, but basically another compiler could optimize let x=e in ... by nesting e , which would trace some trace messages .)
source share