[Haskell-cafe] On the purity of Haskell
Steve Horne
sh006d3592 at blueyonder.co.uk
Wed Dec 28 22:45:34 CET 2011
On 28/12/2011 20:44, Heinrich Apfelmus wrote:
> Steve Horne wrote:
>> This is just my view on whether Haskell is pure, being offered up for
>> criticism. I haven't seen this view explicitly articulated anywhere
>> before, but it does seem to be implicit in a lot of explanations - in
>> particular the description of Monads in SBCs "Tackling the Awkward
>> Squad". I'm entirely focused on the IO monad here, but aware that
>> it's just one concrete case of an abstraction.
>>
>> Warning - it may look like trolling at various points. Please keep
>> going to the end before making a judgement.
>>
>> To make the context explicit, there are two apparently conflicting
>> viewpoints on Haskell...
>>
>> 1. The whole point of the IO monad is to support programming with
>> side-effecting actions - ie impurity.
>> 2. The IO monad is just a monad - a generic type (IO actions), a couple
>> of operators (primarily return and bind) and some rules - within a
>> pure functional language. You can't create impurity by taking a
>> subset of a pure language.
>>
>> My view is that both of these are correct, each from a particular
>> point of view. Furthermore, by essentially the same arguments, C is
>> also both an impure language and a pure one. [...]
>
> Purity has nothing to do with the question of whether you can express
> IO in Haskell or not.
>
...
> The beauty of the IO monad is that it doesn't change anything about
> purity. Applying the function
>
> bar :: Int -> IO Int
>
> to the value 2 will always give the same result:
>
Yes - AT COMPILE TIME by the principle of referential transparency it
always returns the same action. However, the whole point of that action
is that it might potentially be executed (with potentially
side-effecting results) at run-time. Pure at compile-time, impure at
run-time. What is only modeled at compile-time is realized at run-time,
side-effects included.
Consider the following...
#include <stdio.h>
int main (int argc, char*argv)
{
char c;
c = getchar ();
putchar (c);
return 0;
}
The identifier c is immutable. We call it a variable, but the
compile-time value of c is really just some means to find the actual
value in the "big implicit IORef" at runtime - an offset based on the
stack pointer or whatever. Nothing mutates until compile-time, and when
that happens, the thing that mutates (within that "big implicit IORef")
is separate from that compile-time value of c.
In C and in Haskell - the side-effects are real, and occur at run-time.
That doesn't mean Haskell is as bad as C - I get to the advantages of
Haskell at the end of my earlier post. Mostly unoriginal, but I think
the bit about explicit vs. implicit IORefs WRT an alternate view of
transparency is worthwhile.
I hope If convinced you I'm not making one of the standard newbie
mistakes. I've done all that elsewhere before, but not today, honest.
More information about the Haskell-Cafe
mailing list