is a good one. If you want to say that "a mathematical value with
a non-mathematical effect" is nonsensical, more power to you. I said
I don't want to get far into White Knight territory. As long as you
can agree "A mathematical value INTERPRETED BY a physical engine can
have physical effects", we're home and dry.
Here's an analogy that will make the logical contradiction clear. Forget computers and assume you have been asked to referee a paper containing a proof with the following passage:
Let x = ___ (Please fill in the blank)
I think you will agree that would be plainly nonsensical. It's logically equivalent to an input operation ("getInt").
Now back to computers. Given a program text containing the symbol '3', the computer will provide a physical representation: an electromagnetic pattern in a bit of silicon. That's a value; the pattern is to be interpreted as a datum; it is not to be executed. For "getChar", the computer will also provide such a pattern, but this pattern is to be interpreted as executable code, not as a datum. Now suppose we also have an ordinary function like "Add2"; it too will be represented as an electromagnetic pattern, to be interpreted as executable code. getChar and Add2 are not data, except in the trivial sense that all code is data. All three "have an effect" only in the trivial sense that they are physically represented.
In all three cases, the symbolic representation is isomorphic to the physical representation. The 3 will not be executed. When Add2 is executed, the ensuing process is isomorphic to the mathematical function so defined. But when getChar is executed, the ensuing process is not isomorphic to a mathematical function. The process interacts with the non-mathematical world, which a mathematical function can never do. So it has a side effect along with its ordinary representational effect.
The point being that the metalanguage commonly used to describe IO in Haskell contains a logical contradiction. A thing cannot be both a value and a function, but e,g, getChar behaves like a function and has the type signature of a value. I believe this is part of the reason the IO monad is troublesome for beginners (I speak from experience).
-g