
Thomas Davie
On 11 Aug 2010, at 12:39, Ertugrul Soeylemez wrote:
Martijn van Steenbergen
wrote: On 8/2/10 7:09, Ertugrul Soeylemez wrote:
Given the definition of a Haskell function, Haskell is a pure language. The notion of a function in other languages is not:
int randomNumber();
The result of this function is an integer. You can't replace the function call by its result without changing the meaning of the program.
I'm not sure this is fair. It's perfectly okay to replace a call "randomNumber()" by that method's *body* (1), which is what you argue is okay in Haskell.
This is not the same. In Haskell you can replace the function call by its /result/, not its body. You can always do that. But the result of an IO-based random number generator is an IO computation, not a value. It's not source code either, and it's not a function body. It's a computation, something abstract without a particular representation.
It's still rather papering over the cracks to call this pure though. The IO based computation itself still has a result that you *can't* replace the IO based computation with. The fact that it's evaluated by the runtime and not strictly in haskell may give us a warm fuzzy feeling inside, but it still means we have to watch out for a lot of things we don't normally have to in a "very pure"[1] computation.
You can always come up with the necessary transformations to replace a function's call by its body. But this is a trivial result and not related to referential transparency. It's like saying: "You can replace every while loop by a label and a goto". What a discovery! A while loop would be referentially transparent, if it had some notion of a result and you could replace the entire loop by that. And a function is referentially transparent, if you can replace the function's call or equivalently (!) the function's body by the function's result. Referntially transparent functions are inherently memoizable. A C function is definitely not. There is a fundamental difference between an IO computation's result and a Haskell function's result. The IO computation is simply a value, not a function. Its result is something abstract with no concrete representation in Haskell. In fact you can come up with mental models, which make even those computations referentially transparent. For example this one: type IO = State RealWorld You can only use (>>=) to give such a result a name, so you can refer to it. But this is not a function's result. It's a value constructed in some unspecified way and only accessible while running the program. Remember: Referential transparency is a property of source code! Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/