[Haskell-cafe] Use unsafePerformIO to catch Exception?
Jonathan Cast
jonathanccast at fastmail.fm
Wed Mar 25 02:49:32 EDT 2009
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.
jcc
More information about the Haskell-Cafe
mailing list