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
language).

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.
-- 
Robin


More information about the Haskell-Cafe mailing list