Well, the documentation says: Use {-# NOINLINE foo #-} as a pragma on any function foo that calls unsafePerformIO<file:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO>. 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 <lenn...@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_gerg...@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@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe