John D. Earle wrote:
This is a matter that I genuinely at the present time do not grasp and I am hoping that
some of you who are more familiar with the Haskell language may be able to help enlighten
me. I feel the question to be an important one. What material benefit does Haskell derive
from being a "pure" functional language as opposed to an impure one? Please
provide examples as I require instruction.
The following is what I believe to be true at the present time. It seems to be
that the decision was made because it was a matter of taste under the belief
that computer scientists can and often are superstitious and their
superstitions can and often do materially interfere with progress. What I am
saying is that at the present time perhaps due to my ignorance I am unfamiliar
with how this benefits the language in a material sense. It appears to be a
philosophical matter, a matter of identity, what Haskell stands for.
The sort of decision that Apple computer and Microsoft made not to go down the
POSIX road seems relevant. Historically, Apple did not embrace POSIX. Windows
continues to stand for Windows, that is the graphical user interface.
Laziness, referential transparency, equational reasoning,... They're
excellent things, but how about a pragmatic example?
I was working recently on a metaprogramming framework to automate the
generation of a bunch of shell scripts for wiring programs together. To
ensure bug-free scripts we want to maintain a few invariants. One
invariant is that the names of files to be generated should not be
accessible prior to the file actually being generated (to avoid the file
equivalent of a null-pointer dereference). Another invariant is that if
someone wants to run a particular generated script then we should ensure
that all prerequisite scripts are run first (a la any other build system).
After some familiarity with Haskell it's easy to see that what we want
here is a monad. This particular monad keeps track for each value (i.e.,
script) the prerequisite values necessary for it to be valid (i.e.,
tracking all other values used in constructing this one). The monad laws
ensure that no values can escape--- but only with purity. If we could,
for example, make global assignments without altering the type
signatures then it would be possible to smuggle a file name out of the
monadic scope, and thus to violate our invariant about names only being
accessible when they're valid. These sorts of issues were painfully
apparent because I was writing this framework in an impure language for
non-Haskellites to use.
There are many other examples along these lines as well. In general,
purity means we can actually use mathematical notions in a rigorous way
to ensure the program behaves appropriately and are not susceptible to
various logic bugs. Referential transparency and equational reasoning
are just two special-case examples of this general benefit. Having
monads actually be monads is another less recognized one.
Haskell-Cafe mailing list