[Haskell] Re: Global Variables and IO initializers

David Sabel sabel at ki.informatik.uni-frankfurt.de
Sat Nov 6 07:50:13 EST 2004


Inling isn't the only optimization, which can lead to a "wrong" behavior,
"let floating out" and "common subexpression elimination" can also 
change the behavior
of programs using unsafePerformIO.

Our research group has developed  the calculus FUNDIO as a semantic basis:
It's  a non-deterministic call-by-need lambda calculus with a contextual 
equivalence.
Furthermore, with HasFuse there exists a modified implementation of the
Glasgow Haskell Compiler which compiles Haskell programs
using unsafePerformIO in a 'safe' way, i.e. deploys only those optimizations
that have been proved correct w.r.t. FUNDIO.

The technical report describing  FUNDIO is available at
http://www.ki.informatik.uni-frankfurt.de/papers/schauss/FUNDIO.pdf

More information about the related research project "DIAMOND":
http://www.ki.informatik.uni-frankfurt.de/research/diamond/en/

Cheers,
  David

Keean Schupke wrote:

> The problem I see here is how to proove the IO in safeIO is indeed
> safe. Perhaps "UnsafeIO" is a better name, as infact the IO is still
> unsafe - the compiler has to take special notice of this type and
> not inline its definitions.
>
> Your oneShot function has the same problem - if the compiler
> inlines the funtion you get two 'oneShot' functions.
>
> Keean.
>
> Adrian Hey wrote:
>
>> On Friday 05 Nov 2004 7:03 pm, MR K P SCHUPKE wrote:
>>  
>>
>>> Could someone give an example of what these things are that need to be
>>> initialised and that are safe.
>>>   
>>
>>
>> Here's a utility I've concocted for dealing with partial ordering
>> constraints on initialisation of foreign libraries..
>>
>> oneShot :: IO a -> IO (IO a)
>> oneShot io = mdo mv <- newMVar $ do a <- io
>>                                     let loop = do putMVar mv loop
>>                                                   return a
>>                                     loop
>>                  return $ do act <- takeMVar mv
>>                              act
>>
>> The idea being that oneShot takes a real initialising action
>> as argument and returns a new action which will perform the
>> real initialisation at most once, no matter how many times it's
>> used.
>>
>> Suppose I want to use this to create a userInit (which is exported)
>> from a realInit (which isn't exported).
>>
>> Currently I have to write..
>>
>> userInit :: IO <whatever>
>> userInit = unsafePerformIO $ oneShot realInit
>>
>> but I think what I would really like is something like
>> this perhaps..
>>
>> -- For use from SafeIO monad
>> oneShotSafeIO :: IO a -> SafeIO (IO a)
>> <same definition>
>>
>> -- For use from IO monad
>> oneShotIO :: IO a -> IO (IO a)
>> oneShotIO io = liftSafeIO $ oneShotSafeIO io
>>
>> userInit :: IO <whatever>
>> userInit <- oneShotSafeIO realInit
>>
>> Though this could be simplified if SafeIO could be made a
>> sub-type of IO I guess (but I don't know a way to do this).
>>
>> Regards
>> -- 
>> Adrian Hey
>>
>> _______________________________________________
>> Haskell mailing list
>> Haskell at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell
>>  
>>
>
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell




More information about the Haskell mailing list