[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