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

Lennart Augustsson lennart at augustsson.net
Thu Apr 16 04:18:47 EDT 2009


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
>


More information about the Haskell-Cafe mailing list