
The trick of controlling allocation of external resources by using NOINLINE, unsafePerfromIO, and IORef to create global variables has become an indispensable technique in Haskell. It seems to work well enough with most current compilers. However, it is well known that the semantics of NOINLINE are not sufficient to guarantee that this is safe. In principle, the runtime is permitted to GC and reinstantiate these things at any time. Also, it would be nice if we could have a guarantee that global constants are not instantiated until first use. That would allow us to skip the IORef in some cases. I think this issue needs to be addressed in Haskell'. (If it has already, please accept my apologies.) Since NOINLINE has more general use, perhaps there should be a new pragma for this purpose. Thanks, Yitz

Hello Yitzchak, Thursday, February 1, 2007, 1:13:48 PM, you wrote: there is common proposal that i support. example of its use: i :: IORef Int i <- newIORef 1 with a semantics equivalent to current use of usafePerformIO+INLINE in GHC -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hi Bulat, You wrote:
there is common proposal that i support. example of its use:
i :: IORef Int i <- newIORef 1
with a semantics equivalent to current use of usafePerformIO+INLINE in GHC
Are the details of this posted anywhere? Is there a ticket for this? I assume you mean that this will work for anything in the IO monad, not just newIORef. I really like this approach - it is much cleaner than a pragma with unsafePerformIO. Regards, Yitz

On 01/02/07, Bulat Ziganshin
there is common proposal that i support. example of its use:
i :: IORef Int i <- newIORef 1
with a semantics equivalent to current use of usafePerformIO+INLINE in GHC
I think that's too safe-looking. Anything that translates to something involving unsafe* should be tagged with 'unsafe' somewhere as well. Also, as unsafe* is still compiler specific, I think a pragma is probably most appropriate: {-# GLOBAL-MUTVAR #-} i :: IORef Int i = unsafePerformIO (newIORef 1) -- -David House, dmhouse@gmail.com

On Thu, 1 Feb 2007, David House wrote:
I think that's too safe-looking. Anything that translates to something involving unsafe* should be tagged with 'unsafe' somewhere as well. Also, as unsafe* is still compiler specific, I think a pragma is probably most appropriate:
{-# GLOBAL-MUTVAR #-} i :: IORef Int i = unsafePerformIO (newIORef 1)
There might be a more sensible way to handle it while retaining the meat of Bulat's proposal, but I don't think it can really be done without making significant changes to the module system - it amounts to having initialiser actions, and once you've got those there're all sorts of things that rapidly become desirable. I've had a couple of occasions where being able to treat an entire module as being within a monad or an arrow could've been used to good effect though. -- flippa@flippac.org "The reason for this is simple yet profound. Equations of the form x = x are completely useless. All interesting equations are of the form x = y." -- John C. Baez

On 2007 Feb 1, at 11:51 AM, David House indited:
On 01/02/07, Bulat Ziganshin
wrote: there is common proposal that i support. example of its use:
i :: IORef Int i <- newIORef 1
with a semantics equivalent to current use of usafePerformIO +INLINE in GHC
I think that's too safe-looking. Anything that translates to something involving unsafe* should be tagged with 'unsafe' somewhere as well. Also, as unsafe* is still compiler specific, I think a pragma is probably most appropriate:
{-# GLOBAL-MUTVAR #-} i :: IORef Int i = unsafePerformIO (newIORef 1)
Hear hear! As a Haskell newbie things are hard enough to keep straight without that kind of magical unsafe stuff going on. Just sayin' --D'gou

On Thu, Feb 01, 2007 at 04:51:39PM +0000, David House wrote:
I think that's too safe-looking. Anything that translates to something involving unsafe* should be tagged with 'unsafe' somewhere as well. Also, as unsafe* is still compiler specific, I think a pragma is probably most appropriate:
then pretty much everything will have to be 'unsafe' :) look inside of how the libraries are implemented and they all involve unsafe operations at some point, 'unsafe' does not mean unsafe always, it means it is up to the user to provide proofs of certain properties rather than the compiler. when such a proof is provided and abstracted by an API, then it is safe. As to this particular extension, depending on the exact details it can be safe or unsafe and make different demands on the implementation. luckily, pretty much all of this was worked out in a discussion a while ago, the trick was to create a new type 'ACIO' which contained only 'good' top level operations. There will be an 'unsafeIOToACIO' of course, I mean, ACIO functions have to be implemented somehow. :) John -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham wrote:
luckily, pretty much all of this was worked out in a discussion a while ago, the trick was to create a new type 'ACIO' which contained only 'good' top level operations. There will be an 'unsafeIOToACIO' of course
Hmm. There was a long thread about this in Nov. 2004 on haskell-cafe with a number of proposals. One person characterized that thread as a "religious war". Is there a ticket for this issue? I know it is a bit late in the process, but this is an important hole in Haskell 98 that should be fairly easy to plug. It would be a shame to miss the opportunity. Thanks, Yitz
participants (6)
-
Bulat Ziganshin
-
David House
-
Douglas Philips
-
John Meacham
-
Philippa Cowderoy
-
Yitzchak Gale