[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