[Haskell-cafe] ANN: Elerea, another FRP library

Bulat Ziganshin bulat.ziganshin at gmail.com
Thu Apr 16 06:14:39 EDT 2009


Hello Peter,

Thursday, April 16, 2009, 12:29:41 PM, you wrote:

Lennart (and Patai) said about unsafePerformIO, you - about NOINLINE

> Well, the documentation says:
> Use {-# NOINLINE foo #-} as a pragma on any function foo that calls
> unsafePerformIO. If the call is inlined, the I/O may be performed more than once.
>  
> So you claim this does not prevent GHC to inline it anyway? That
> feels like a bug then, both in the documentation and NOINLINE 

> On Thu, Apr 16, 2009 at 10:18 AM, Lennart Augustsson <lennart at augustsson.net> wrote:
>  
> There's no guarantee about unsafePerformIO not being inlined, that's
>  just how ghc treats it.
>  
>  2009/4/16 Patai Gergely <patai_gergely at fastmail.fm>:
>  
>>> On the other hand, breaking referential transparency in the
 >>> external interface is a very bad idea, in my opinion. Actually,
 >>> this means that the library user would have to turn certain
 >>> compiler optimizations off to get the intended behavior.
 >> However, in practice you can compile Elerea with -O2 without ill
 >> effects. In fact, that's what happens if you install it with cabal.
 >>
 >>> Just have a look at the Haddock docs of unsafePerformIO.
 >> Yes, I did that too, and came up with the following checklist:
 >>
 >> - the order of side effects doesn't matter much, since the resulting
 >> networks are equivalent if we don't rely on the automatic delay feature
 >> (applicative optimisations can be different, but still with the same net
 >> effect)
 >> - unsafePerformIO is apparently never inlined, i.e. each instance is
 >> executed once, so sharing works as desired
 >> - let-floating is no problem, because all instances of unsafePerformIO
 >> rely on surrounding function arguments
 >> - CSE is no problem either, it even helps if it's performed (and it is
 >> with optimisations turned on), since it results in smaller equivalent
 >> networks
 >>
 >> I think we can expect it to be fairly well-behaving, because the 'side
 >> effect' of Elerea primitives is basically the same as that of pure
 >> values in general: upon evaluation a value is created in the memory and
 >> we get a reference to it. We only have an extra constraint for the
 >> compiler: never duplicate these values. Merging identical ones is okay,
 >> and in fact desirable. The following code demonstrates this if you
 >> compile it with and without optimisations:
 >>
 >> import Control.Applicative
 >> import Control.Monad
 >> import FRP.Elerea
 >> import System.IO.Unsafe
 >>
 >> cint a b = unsafePerformIO (putStrLn "!") `seq`
 >>           transfer 0 (\dt x x0 -> x0+x*dt) b
 >>
 >> mysig = (latcher 0 (b >@ 0.3) (const (cint a b) <$> cint a b)) +
 >>        (cint a b) + (cint a b) + a
 >>    where a = pure 4
 >>          b = stateful 0 (+)
 >>
 >> main = replicateM 10 (superstep mysig 0.1) >>= print
 >>
 >> I'd like to see an example where optimisation does make a difference,
 >> because I'm still unsure about the consequences of 'unsafeness'.
 >>
 >> Gergely
 >>
 >> --
 >> http://www.fastmail.fm - Or how I learned to stop worrying and
 >>                          love email again
 >>
 >> _______________________________________________
 >> Haskell-Cafe mailing list
 >> Haskell-Cafe at haskell.org
 >> http://www.haskell.org/mailman/listinfo/haskell-cafe
 >>
>  _______________________________________________
>  Haskell-Cafe mailing list
>  Haskell-Cafe at haskell.org
>  http://www.haskell.org/mailman/listinfo/haskell-cafe
>  


>   


-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin at gmail.com



More information about the Haskell-Cafe mailing list