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

Patai Gergely patai_gergely at fastmail.fm
Thu Apr 16 04:06:49 EDT 2009


> 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



More information about the Haskell-Cafe mailing list