cobbpg / elerea

A simple FRP library providing leak-free first-class streams.
BSD 3-Clause "New" or "Revised" License
116 stars 8 forks source link

Strange behaviour of 'effectful' #6

Closed fbinz closed 10 years ago

fbinz commented 11 years ago

In the following program I use effectful to print something on every iteration. However it only prints a few times (exact number of times varies from run to run) and then stops. The code uses the driveNetwork function from elerea-examples:

import Control.Applicative
import Control.Monad
import Control.Concurrent (threadDelay)

import FRP.Elerea.Param

main = do
    network <- start $ do
        effectful $ print "test"
        return . return . return $ ()

    driveNetwork network $ do
        threadDelay 100000
        return $ Just undefined

driveNetwork network driver = do
  dt <- driver
  case dt of
    Just dt -> do join (network dt)
                  driveNetwork network driver
    Nothing -> return ()

I'm using GHC 7.6.3 (Haskell Plattform) on Windows. Sometimes it takes a while until it stops printing, but it always stops at some point...

cobbpg commented 11 years ago

Yes, this is a known issue, and in fact a conceptual problem. The effectful signal gets garbage collected because its output is not used. The solution is to keep the thread alive by adding the dummy signal returned by the constructor to the data-flow network in a way that won’t affect the output; liftA2 const does the trick. For instance, we needed to do this when building an Elerea interface over the Bullet physics engine:

http://lambdacube3d.wordpress.com/2012/11/16/using-bullet-physics-with-an-frp-approach-part-2/

You can think of the dummy signal as an object that represents the effectful thread. In order to kill the thread, you need to detach the dummy signal from the network. I’m not happy about this issue, but so far failed to come up with a clean and fool-proof way of adding effects to signals...