"D. Tweed" wrote:

> On Tue, 27 Jul 1999, Simon Marlow wrote:
> > > req a b = unsafePerformIO $ do
> > >    a' <- makeStableName a
> > >    b' <- makeStableName b
> > >    return (a' == b')
> >
> > That's exactly what to use in a situation like this.  Pointer equality loses
> > referential transparency in general (as Simon P.J. pointed out), hence the
> > use of the I/O monad in our Stable Name API.
> >
> > Furthermore, if you intend to encapsulate your use of pointer equality in a
> > "safe" abstraction, say a memo table, then use of unsafePerformIO is
> > entirely justified.  The req function above is of course an "unsafe"
> > abstraction, because it exposes the representation of a and b.
>
> Just an idle curiousity question: when you say it loses referential
> transparency am I right in saying it this is only with respect to compile
> time transformations (& program proofs,etc) but that there's no problem
> _for a given compiled program_ about req a b changing it's value depending
> upon the way demand drives the lazy evaluation reduction strategy, or is
> there a subtlety there?

A particular call to `req' may change from True to False or vice versa
between different runs of the program.  Just imagine a parallel implementation
that does things "behind your back".  And every implementation has one
of those!  It's called the garbage collector. :-)
I know that the hbc garbage collector happily does things that changes
the sets of objects that are pointer equal before and after a GC.

So I think IO is a good place to put it.  If Haskell had a Nondeterministic monad
then that would be the place.

--

        -- Lennart





Reply via email to