[Haskell] Re: Question for the haskell implementors: Arrays, unsafePerformIO, runST

John Meacham john at repetae.net
Tue Feb 21 00:02:10 EST 2006

After reading all the interesting responses I decided to go with a
slight generalization of my original idea, and it surprisingly turns out
to have other generally useful unintended uses, which is the point that a 'hack'
becomes a 'feature'. :)

before I had a primitive:
newWorld__ :: a -> World__

which took an arbitrary value, discarded it, and returned a world. thus
letting your World__ depend on an arbitrary haskell expression and
therefore not be floatable any further than said expression.

I generalized this primitive to 

drop__ :: a -> b -> b

which discards its first argument and just passes on its second. so
newWorld__ becomes

newWorld__ x = drop__ x World__

now, the interesting thing is that with the drop__ primitive you can
generally solve floating and cse problems.


f x = ... where
        z = cheapfunction constant

where cheapfunction produces something big youd rather the garbage
collector not hold on to between calls to f, then you can do 

f x = ... where
        z = cheapfunction (drop__ x constant)

now the call artificaly depends on the argument x so it won't be floated
out and is guarenteed to be reevaluated on every call to f.

Another issue drop__ can help with is unintential CSE, generally an
issue with global variables forcing you too turn off CSE module-wide to
avoid issues (or perhaps program-wide in the presence of whole-program

{-# NOINLINE var1 #-}
var1 :: IORef Int
var1 = unsafePerformIO $ newIORef 0

{-# NOINLINE var2 #-}
var2 :: IORef Int
var2 = unsafePerformIO $ newIORef 0

now, var1 and var2 have the exact same body and type and thus are
candidates for CSE, which would be quite bad as it would replace two
variables with one.

data Var1 = Var1
data Var2 = Var2
var1 = unsafePerformIO $ newIORef (drop__ Var1 0)
var2 = unsafePerformIO $ newIORef (drop__ Var2 0)

now they can't be commoned up because Var1 and Var2 are distinct.

In any case, this seems like it might be a useful primitive for other
haskell implementations to provide and solves a few problems custom
pragmas have been proposed for in the past.


John Meacham - ⑆repetae.net⑆john⑈

More information about the Haskell mailing list