[Haskell-cafe] Functional vs Imperative

Thomas Davie tom.davie at gmail.com
Tue Sep 13 09:55:14 EDT 2005

On 13 Sep 2005, at 14:45, Dhaemon wrote:

> Hello,
> I'm quite interested in haskell, but there is something I don't  
> understand(intuitively). I've been crawling the web for an answer,  
> but nothing talks to me...
> So I was hoping I could find some help here:
> "How is evaluating an expression different from performing action?"
> I'm puzzled... Doesn't it amount to the same thing? Maybe I have a  
> wrong definition of "evaluating"(determine the value of an  
> expression)?
> Examples would be appreciated.
> Also, just for kicks, may I had this: I read the code of some  
> haskell-made  programs and was astonished. Yes! It was clean and  
> all, but there were "do"s everywhere... Why use a function language  
> if you use it as an imperative one?(i.e. most of the apps in http:// 
> haskell.org/practice.html)

The difference is all about referential transparency -- in short, a  
function given the same inputs will always give the same result.   
This is not the same as in imperative languages, where functions/ 
methods/actions can have 'side-effects' that change the behavior of  
the rest of the program.

Take this example:

C program:
#define square(x) ((x) * (x))
#define inc(x) ((x)++)

int myFunc (int *x)
     return square(inc(*x));

the C preprocessor will re-write the return line to:
return ((((x)++)) * (((x)++)));

this will be performed in sequence, so, x will be incremented  
(changing the value of x), and that result will be multiplied by x  
incremented again.

so if we run myFunc(&y), where y is 5, what we get is 5 incremented  
to 6, and them multiplied by 6 incremented to 7.  So the result of  
the function is 42 (when you might reasonably expect 36), and y is  
incremented by 2, when you might reasonably expect it to be  
incremented by 1.

Haskell program:

square x = x * x
inc = (+1)
myFunc = square . inc

and we now call myFunc 5, we get this evaluation:

myFunc 5 is reduced to (square . inc) 5
(square . inc) 5 is reduced to square (inc 5)
square (inc 5) is reduced to square ((+1) 5)
square ((+1) 5) is reduced to square 6
square 6 is reduced to 6 * 6
6 * 6 is reduced to 36

If you want to study these reductions on a few more examples, you  
might want to download the Hat tracer, and use hat-anim to display  
reductions step by step.


More information about the Haskell-Cafe mailing list