On 11-06-08 11:17 PM, Gregory Guthrie wrote:
> So the implication of the rules:
> 1) all IO must start from the top level, and there is only one IO
> 2) you cannot extract anything from an IO
>> Seems to be that the whole program structure becomes a series of do... blocks, which is basically a sequential imperative looking style.
> The general advice of "Strive to keep as much of the program pure as possible" thus seems difficult.
Suppose you teach Java or C++ or any OOP, and you give out this basic
homework to beginners: write a program to take two complex numbers from
the user, then print their sum. You are assured to receive such flawed
design:
class complex {
double r, i;
public:
complex() {
cout << "please enter the real part:";
cin >> r;
cout << "please enter the imaginary part:";
cin >> i;
}
}
The urge to do I/O at all the wrong places is a born instinct. Humanity
strives to organize programs (and articles) by stream of consciousness
rather than by separation of concerns. Why do they ask the user in the
constructor? Because that's where the editor cursor was when they
remembered to ask the user. Similarly in Haskell, why do they read input
in the data processing function? Because that's where the editor cursor
was when they remembered to read input. This is universal to FP, OOP,
IP, any P, with or without language restrictions.
For people who organize programs by stream of consciousness, Haskell's
separation of IO does not help, but SML's and C++'s non-separation does
not help either. Nothing helps. Don't worry about them.
For people who organize programs by separation of concerns, such as you
and me: Haskell's separation of IO helps. This is what matters.