[Haskell-cafe] On the purity of Haskell
Steve Horne
sh006d3592 at blueyonder.co.uk
Thu Dec 29 05:52:57 CET 2011
On 29/12/2011 01:53, Antoine Latter wrote:
> 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.
>>
> I don't think I would put it that way - the value 'bar 2' is a regular
> Haskell value. I can put it in a list, return it from a function and
> all other things:
>
> myIOActions :: [IO Int]
> myIOActions = [bar 2, bar (1+1), bar (5-3)]
>
> And I can pick any of the elements of the list to execute in my main
> function, and I get the same main function either way.
Yes - IO actions are first class values in Haskell. They can be derived
using all the functional tools of the language. But if this points out a
flaw in my logic, it's only a minor issue in my distinction between
compile-time and run-time.
Basically, there is a phase when a model has been constructed
representing the source code. This model is similar in principle to an
AST, though primarily (maybe entirely?) composed of unevaluated
functions rather than node-that-represents-whatever structs. This phase
*must* be completed during compilation. Of course evaluation of some
parts of the model can start before even parsing is complete, but that's
just implementation detail.
Some reductions (if that's the right term for a single evaluation step)
of that model cannot be applied until run-time because of the dependence
on run-time inputs. Either the reduction implies the execution of an IO
action, or an argument has a data dependency on an IO action.
Many reductions can occur either at compile-time or run-time.
In your list-of-actions example, the list is not an action itself, but
it's presumably a part of the expression defining main which returns an
IO action. The evaluation of the expression to select an action may have
to be delayed until run-time with the decision being based on run-time
input. The function that does the selection is still pure. Even so, this
evaluation is part of the potentially side-effecting evaluation and
execution of the main IO action. Overall, the run-time execution is
impure - a single side-effect is enough.
So... compile-time pure, run-time impure.
More information about the Haskell-Cafe
mailing list