Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I/O in Haskell is Functional?

I'm just starting to take a look at Haskell (my previous FP experience is in Scheme), and I came across this code:

do { putStrLn "ABCDE" ; putStrLn "12345" }

To me, this is procedural programming, if anything -- especially because of the consecutive nature of side effects.

Would someone please explain how this code is "functional" in any respect?

like image 730
user541686 Avatar asked Jun 19 '11 00:06

user541686


3 Answers

While it appears to be a procedural program, the above syntax is translated into a functional program, like so:

   do { putStrLn "ABCDE" ; putStrLn "12345" }
=>
   IO (\ s -> case (putStrLn "ABCDE" s) of
                  ( new_s, _ ) -> case (putStrLn "12345" new_s) of
                                      ( new_new_s, _) -> ((), new_new_s))

That is, a series of nested functions that have a unique world parameter threaded through them, sequencing calls to primitive functions "procedurally". This design supports an encoding of imperative programming into a functional language.

The best introduction to the semantic decisions underlying this design is "The Awkward Squad" paper,

enter image description here

like image 82
Don Stewart Avatar answered Sep 26 '22 11:09

Don Stewart


I don't think we can answer this question clearly, because "functional" is a fuzzy notion, and there are contradictory ideas out there of what it means. So I prefer Peter Landin's suggested replacement term "denotative", which is precise and substantive and, for me, the heart & soul of functional programming and what makes it good for equational reasoning. See these comments for some pointers to Landin's definition. IO is not denotative.

like image 13
Conal Avatar answered Sep 27 '22 11:09

Conal


Think about it this way. It doesn't actually "execute" the IO instructions. The IO monad is a pure value that encapsulates the "imperative computation" to be done (but it doesn't actually carry it out). You can put monads (computations) together into a bigger "computation" in a pure way using the monad operators and constructs like "do". Still, nothing is "executed" per se. In fact, in a way the whole purpose of a Haskell program is to put together a big "computation" that is its main value (which has type IO a). And when you run the program, it is this "computation" that is run.

like image 5
newacct Avatar answered Sep 27 '22 11:09

newacct