[Haskell-cafe] Use unsafePerformIO to catch Exception?

Jonathan Cast jonathanccast at fastmail.fm
Wed Mar 25 11:14:54 EDT 2009


On Wed, 2009-03-25 at 07:39 -0400, Xiao-Yong Jin wrote:
> Jonathan Cast <jonathanccast at fastmail.fm> writes:
> 
> > On Tue, 2009-03-24 at 23:13 -0700, Donn Cave wrote:
> >> Quoth Duncan Coutts <duncan.coutts at worc.ox.ac.uk>:
> >> 
> >> > You must not do this. It breaks the semantics of the language.
> >> >
> >> > Other people have given practical reasons why you should not but a
> >> > theoretical reason is that you've defined a non-continuous function.
> >> > That is impossible in the normal semantics of pure functional languages.
> >> > So you're breaking a promise which we rely on.
> >> 
> >> Could you elaborate a little, in what sense are we (?) relying on it?
> >> 
> >> I actually can't find any responses that make a case against it on a
> >> really practical level - I mean, it seems to be taken for granted that
> >> it will work as intended,
> >
> > It shouldn't be.
> >
> > Consider:
> >
> >     loop = loop
> >     blam = error "blam"
> >     notReallyTry = unsafePerformIO . try . evaluate
> >
> > Now, normally, we have, for all x, y,
> >
> >       x `seq` y `seq` x
> >     = y `seq` x
> >
> > But we clearly do *not* have this for x = blam, y = loop, since the
> > equality isn't preserved by notReallyTry:
> >
> >     notReallyTry $ blam `seq` loop `seq` blam = Left (ErrorCall "blam")
> >     notReallyTry $ loop `seq` blam            = loop
> >
> > Now, say a compiler sees the definition
> >
> >     foo x y = x `seq` y `seq` x
> >
> > in one module, and then in a later one
> >
> >     expectToBeTotal = notReallyTry $ foo blam loop
> >
> > ?  What happens if the compiler, while compiling foo, notices that x is
> > going to be evaluated eventually anyway, and decides against forcing it
> > before y?
> >
> > What if foo was written as
> >
> >     foo (!x) (!y) = x
> >
> > ?  Which order are the evaluations performed in?  In a purely functional
> > language, it doesn't matter; but all of a sudden with impure operations
> > like notReallyTry popping up, it does.
> 
> Could you elaborate more about why this kind of breakage
> wouldn't happen if 'try' is used in an IO monad as intended?

It would.  But it would happen in IO, which is allowed to be
non-deterministic.  Pure Haskell is not allowed to be non-deterministic.

jcc




More information about the Haskell-Cafe mailing list