State monads don't respect the monad laws in Haskell
John Launchbury
john@launchbury.org
Wed, 15 May 2002 09:48:28 -0700
I watched with interest the discussion about the ravages of `seq`.
In the old days, we protected uses of `seq` with a type class, to keep it at
bay. There was no function instance (so no problem with the state monads, or
lifting of functions in general), and the type class prevented interference
with foldr/build.
However...
In defining Haskell 98 we made a conscious decision not to guard `seq` with
a type class. The reasoning was as follows:
+ Space control is an important phase of programming, and `seq` provides
a powerful mechanism for tweaking a program, to improve its space
behavior. It should therefore be as easy as possible to experiment
with adding `seq` in various places, including on function closures.
- Haskell already had somewhat muddied semantics for types (both sums
and products are lifted, and bottom is present in every type). It
seemed as though a little more muddying was not a serious affair.
Did we make the right decision? For Haskell 98: Yes. And I believe we made
it with our eyes open.
Will the next version of Haskell have something better. I hope so, but I
fear not.
First, I don't see much active research on what Haskell would look like with
true unpointed types -- there are lots of practical issues to be addressed;
second, the prevalence of things like unsafePerformIO (slogan: USPIO is NOT
Haskell) seems to be growing, not diminishing, and again I don't see much
active research on how to gain its benefits while containing its damage.
True declarative programming is a delicate flower.
Review the history of the 80's and early 90's. It was the conviction of the
Lazy FP community to true declarativeness that led us all to reject proposal
after proposal for state and efficient arrays, until finally Eugenio and
Phil led us to the land of monads. Finally, as a result of the burning need
we all felt, and of the high standards we all demanded, we could be as
imperative as the best of them, without compromising the mathematical nature
of the language. If this history teaches us anything, it should urge us all,
and the new young blood in particular, not to go for quick fixes, or to
compromise on the dream of a truly declarative language.
Haskell 98 is a great language. The best on the planet today. But it's not
perfection. Let's confront the problems face to face, and find the right way
forward!
John
>>> And I'd really much rather we cleaned up the semantics of
>>> seq---or better yet, fixed the problems with lazy evaluation which
>>> make seq necessary in the first place.
>>
>> A general question: What is seq useful for, other than efficiency?
>
> seq can create a new, strict definition of a function from an existing
> non-strict function.