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

Lennart Augustsson lennart at augustsson.net
Thu Apr 16 06:40:50 EDT 2009


With NOINLINE you should be safe, but you never mentioned that originally. :)

On Thu, Apr 16, 2009 at 10:29 AM, Peter Verswyvelen <bugfact at gmail.com> wrote:
> 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
>
>


More information about the Haskell-Cafe mailing list