DDC compiler and effects; better than Haskell? (was Re: [Haskell-cafe] unsafeDestructiveAssign?)

Robin Green greenrd at greenrd.org
Tue Aug 11 20:16:56 EDT 2009

On Wed, 12 Aug 2009 08:34:28 -0500
Derek Elkins <derek.a.elkins at gmail.com> wrote:

> On Tue, Aug 11, 2009 at 3:51 PM, Robin Green<greenrd at greenrd.org>
> wrote:
> > On Wed, 12 Aug 2009 11:37:02 +0200
> > Peter Verswyvelen <bugfact at gmail.com> wrote:
> >
> >> Yes, sorry.
> >>
> >> But I think I already found the answer to my own question.
> >>
> >> DDC functions that are lazy don't allow side effects:
> >> http://www.haskell.org/haskellwiki/DDC/EvaluationOrder
> >>
> >> Anyway it would be cool if the DDC EffectSystem would also work on
> >> lazy functions :)
> >
> > As was just pointed out in the unsafeDestructiveAssign thread from
> > which this thread was forked, effects are incompatible with
> > non-strict evaluation.
> No, they aren't.  At least, they aren't in any technical way.  There
> have been more than a few languages supporting both laziness and
> mutation starting with Algol.

OK, explicitly creating thunks, like in Algol, LISP and CAL, can work,
because you can either prevent the programmer from using mutation
inside a thunk (as in the CAL approach), or rely on the programmer to
ensure that mutations are only done in a safe order (as in the
"callback as thunk" approach, which can be done in almost any impure

But if almost *every* expression is a thunk, as in a non-strict
language like Haskell, and if moreover evaluation order can differ
depending on the compiler/interpreter, or compiler version, or compiler
flags, it becomes impractical to combine them. So yes, I agree, it's
not an absolute technical incompatibility, it's a practical one.

> > Also, effects would destroy modular reasoning.
> Again, it is purity, not laziness, that allows compositional
> reasoning.  Effects destroy compositional reasoning in a strict
> language just as much.

Not really - in a strict language, if in method M action A always
happens before action B, then that fact will remain true in whichever
context M is called (ignoring threading issues). In a non-strict, impure
language, assuming monads are not used, if you have a function f which
performs actions A and B, and two other functions g and h which both
call f, the actions could happen in one order in g, and in the opposite
order - or not at all - in h, because of a difference in data demanded
by each function. Indeed, unless g and h are "top-level" functions (in
the sense that they are main functions or invoked from some
ghci-equivalent) the notion of "the" order the actions are performed in
is ill-defined, because it could vary depending on which function g or
h is being called from.

Now, you could say, the strict order of evaluation can be simulated in
a non-strict language on a case-by-case basis by using monads or
whatever. Well, yes, but that would be missing the point, because the
original point of this discussion was to avoid having to use monads.

More information about the Haskell-Cafe mailing list