
I've noticed quite a few pages referencing constructs such as: var :: MVar ([Foo]) var = unsafePerformIO (newMVar ([])) and the likes. Is there a danger of different uses of 'var' getting new MVars instead of all sharing one. Having a reliable way to create a piece of global state would be very convenient. Dave

On Tue, 06 Mar 2007 12:03:05 -0800
David Brown
I've noticed quite a few pages referencing constructs such as:
var :: MVar ([Foo]) var = unsafePerformIO (newMVar ([]))
and the likes. Is there a danger of different uses of 'var' getting new MVars instead of all sharing one.
Having a reliable way to create a piece of global state would be very convenient.
This operation is unsafe by definition. I use it extensively, without problems. The "unsafe" in the name reminds you that there are situations for which the function is inappropriate, but all of my deployed commercial programs have functionality of this sort. Understand the risk, but don't hesitate to use it. Seth Kurtzberg
Dave
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Seth Kurtzberg wrote:
On Tue, 06 Mar 2007 12:03:05 -0800 David Brown
wrote: I've noticed quite a few pages referencing constructs such as:
var :: MVar ([Foo]) var = unsafePerformIO (newMVar ([]))
and the likes. Is there a danger of different uses of 'var' getting new MVars instead of all sharing one.
Having a reliable way to create a piece of global state would be very convenient.
This operation is unsafe by definition. I use it extensively, without problems. The "unsafe" in the name reminds you that there are situations for which the function is inappropriate, but all of my deployed commercial programs have functionality of this sort. Understand the risk, but don't hesitate to use it.
Do you do anything to keep 'var' from getting inlined? I can envision a case where the code would be inlined, and then each use would get a separate MVar. Thanks, Dave

Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe. On Mar 6, 2007, at 23:18 , David Brown wrote:
Seth Kurtzberg wrote:
On Tue, 06 Mar 2007 12:03:05 -0800 David Brown
wrote: I've noticed quite a few pages referencing constructs such as:
var :: MVar ([Foo]) var = unsafePerformIO (newMVar ([]))
and the likes. Is there a danger of different uses of 'var' getting new MVars instead of all sharing one.
Having a reliable way to create a piece of global state would be very convenient.
This operation is unsafe by definition. I use it extensively, without problems. The "unsafe" in the name reminds you that there are situations for which the function is inappropriate, but all of my deployed commercial programs have functionality of this sort. Understand the risk, but don't hesitate to use it.
Do you do anything to keep 'var' from getting inlined? I can envision a case where the code would be inlined, and then each use would get a separate MVar.
Thanks, Dave
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Hi
On 3/6/07, Lennart Augustsson
Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.
Couldn't GHC bake in knowledge about unsafePerformIO, and never inline it? It is a slightly hacky solution, but since unsafePerformIO is pretty much only used in hacks, I think its almost fitting. Thanks Neil

Neil Mitchell wrote:
On 3/6/07, Lennart Augustsson
wrote: Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.
Couldn't GHC bake in knowledge about unsafePerformIO, and never inline it? It is a slightly hacky solution, but since unsafePerformIO is pretty much only used in hacks, I think its almost fitting.
It seems to be used a bit more than just as a hack. Many things that interface with the real world, but try to present lazy interfaces have to use it. Maintaining a shared state that doesn't have to be passed around to everything that uses it isn't really a hack. As an example, I would like to have something that performs logging, and is used by many clients. Without the unsafePerformIO, everything has to somehow find and pass around the state of this logging system, whereas with it, it can just allocate one when first needed. Non-strict semantics are kind of a new thing for me. I'm still trying to get a good grasp of what can be lazy, what should live in the IO Monad, and what should have a carefully crafted "bridge" between the two. Things like hGetContents have somewhat set a trend here. Dave

I wouldn't like if unsafePerformIO could never be inlined, sometimes you want it inlined for performance. And not all uses are hacky, it's just that when I use it, then burden is on me to convince myself that it is safe. On Mar 6, 2007, at 23:56 , Neil Mitchell wrote:
Hi
On 3/6/07, Lennart Augustsson
wrote: Yeah, you really need {-# NOINLINE var #-} to make it reasonable safe.
Couldn't GHC bake in knowledge about unsafePerformIO, and never inline it? It is a slightly hacky solution, but since unsafePerformIO is pretty much only used in hacks, I think its almost fitting.
Thanks
Neil

Lennart Augustsson wrote:
I wouldn't like if unsafePerformIO could never be inlined, sometimes you want it inlined for performance. And not all uses are hacky, it's just that when I use it, then burden is on me to convince myself that it is safe.
unsafePerformIO is currently not inlined - there's a NOINLINE pragma on its definition in GHC.IOBase, and some comments in there to explain why. You're right that sometimes you really want it to be inlined - this is why there's a function called inlinePerformIO in Data.ByteString.Base, for example. You'd better really know what you're doing before using that one, though :-) Cheers, Simon

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Simon Marlow wrote:
You're right that sometimes you really want it to be inlined - this is why there's a function called inlinePerformIO in Data.ByteString.Base, for example. You'd better really know what you're doing before using that one, though :-)
yep, it should be generally available as unsafeInlineUnsafePerformIO (-: It's especially unsafe because... all of the IO might not be executed, due to lazy evaluation + optimization? Some of the IO might be run twice without other parts of it being so? Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFF7p9jHgcxvIWYTTURAqAKAKCu8dJ4rpyMcMH7ebPv0HfIUyGSgACgy0Jq naeTCZk/2xZraOrSJtyObm8= =oKKG -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Brown wrote:
I've noticed quite a few pages referencing constructs such as:
var :: MVar ([Foo]) var = unsafePerformIO (newMVar ([]))
and the likes. Is there a danger of different uses of 'var' getting new MVars instead of all sharing one.
If I remember correctly, you "should" put {-# NOINLINE var #-} on a line just before that.
Having a reliable way to create a piece of global state would be very convenient.
This is well known and extensively discussed - unfortunately it is a complicated (or at least controversial) issue Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFF7fiFHgcxvIWYTTURAoMXAJ9SCryCX+daNLKrMIhWlMh/aJmVXwCghosx 6/lBweYnNslHLal57RAtX0Y= =2oIN -----END PGP SIGNATURE-----
participants (6)
-
David Brown
-
Isaac Dupree
-
Lennart Augustsson
-
Neil Mitchell
-
Seth Kurtzberg
-
Simon Marlow