unsafePerformIO and IORefs

I want to write something like type State a = IORef a newState :: a -> State a newState v = unsafePerformIO (newIORef v) But I don't want the compileer to inline this nor to inline any application of this. {#NOINLINE newState#} But how can I stop this function to be inlined when applied for example : .... let x = newState 0 in {... code where x is used twice ...} How to be sure that x isn't inlined and that all occurences of x are pointing to the same memory place ? Best regards, Nicolas Oury

You can't. CSE (common subexpression elimination) will replace any occurances of 'newState 0' in a function body with the same value. In short: don't use upIO :) If I'm wrong, someone will correct me. But expect a few "what are you trying to do" email messages or people suggesting implicit paremeters or monad wrappers (in fact, count this as the first of said emails). - Hal -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume On Mon, 18 Nov 2002, Nicolas Oury wrote:
I want to write something like
type State a = IORef a
newState :: a -> State a newState v = unsafePerformIO (newIORef v)
But I don't want the compileer to inline this nor to inline any application of this.
{#NOINLINE newState#}
But how can I stop this function to be inlined when applied for example : .... let x = newState 0 in {... code where x is used twice ...}
How to be sure that x isn't inlined and that all occurences of x are pointing to the same memory place ?
Best regards, Nicolas Oury
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Hal Daume III wrote:
You can't. [...]
Well, you can, but only for CAFs. This idiom/hack is used quite happily throughout GHC, HOpenGL, H/Direct, ... Slightly modified stuff from GHC's sources: ------------------------------------------------------------ -- global variables in Haskell :-) ------------------------------------------------------------ global :: a -> IORef a global a = unsafePerformIO (newIORef a) #define GLOBAL_VAR(name,value,ty) \ name :: IORef (ty) ; \ name = global (value) ; \ {-# NOINLINE name #-} ------------------------------------------------------------ -- examples ------------------------------------------------------------ GLOBAL_VAR(counter, 0, Int) GLOBAL_VAR(flag, False, Bool) ------------------------------------------------------------ Cheers, S.

On Mon, Nov 18, 2002 at 10:36:05AM -0800, Hal Daume III wrote:
You can't. CSE (common subexpression elimination) will replace any occurances of 'newState 0' in a function body with the same value.
In short: don't use upIO :)
Sorry, cannot resist to pour a little salt onto the wound :) [232]% grep global ghc/compiler/utils/Util.lhs , global global :: a -> IORef a global a = unsafePerformIO (newIORef a) [233]% ghc/compiler/HsVersions.h: [...] #ifdef __GLASGOW_HASKELL__ #define GLOBAL_VAR(name,value,ty) \ name = Util.global (value) :: IORef (ty); \ {-# NOINLINE name #-} #endif [237]% grep -r GLOBAL_VAR ghc/compiler | wc -l 90 Muahahah... ;-P Cheers, Michael
participants (4)
-
Hal Daume III
-
Michael Weber
-
Nicolas Oury
-
Sven Panne