20

When toying around with implementing FRP one thing I've found that is confusing is what to do with the past? Basically, my understanding was that I would be able to do this with a Behaviour at any point:

beh.at(x) // where time x < now

This seems like it could be problematic performance wise in a case such as this:

val beh = Stepper(0, event) // stepwise behaviour

Here we can see that to evaluate the Behaviour in the past we need to keep all the Events and we will end up performing (at worst) linear scans each time we sample.

Do we want this ability to be available or should Behaviours only be allowed to be evaluated at a time >= now? Do we even want to expose the at function to the programmer?

seadowg
  • 4,033
  • 6
  • 32
  • 43
  • 1
    Why is this tagged Haskell but using Scala syntax? After all, I think the question is language-agnostic :-) – Bergi Sep 11 '14 at 03:56

1 Answers1

20

While a behaviour is considered to be a function of time, reliance on an arbitrary amount of past data in FRP is a Bad Thing, and is referred to as a time leak. That is, transformations on behaviours should generally be streaming/reactive in that they do not rely on more than a bounded amount of the past (and should accumulate this knowledge of the history explicitly).

So, no, at is not desirable in a real FRP system: it should not be possible to look at either the past or the future. (The latter is, of course, impossible, if the state of the future depends on anything external to the FRP system.)

Of course, this leads to the problem that only being able to look at the exact present severely restricts what you can do when writing a function to transform behaviours: Behaviour a -> Behaviour b becomes the same as a -> b, which makes many things we'd like to do impossible. But this is more an issue of finding a semantics, one of FRP's persistent problems, than anything else; as long as the primitive transformations on behaviours you provide are powerful enough without causing time leaks, everything should be fine. For more information on this, see Garbage collecting the semantics of FRP.

ehird
  • 39,804
  • 3
  • 173
  • 180
  • 1
    To be clear: Do you mean we should only ever be able to calculate the value of a Behaviour 'now'? I feel like this makes a lot of sense but I can't find Conal ever actually explaining this... – seadowg Mar 06 '12 at 23:02
  • 1
    Well, calculating the value of a behaviour "at a specific time" is something not covered by the FRP system itself; it is a way of relating the FRP system to the outside world. For instance, in Haskell, such a function might be `value :: Behaviour a -> IO a`. But FRP in the abstract exists in a world with no `IO`: since the definition of a behaviour is a value that changes over time, the only way to represent the current value of a behaviour is... with a behaviour! – ehird Mar 07 '12 at 00:00
  • But, as far as gluing an FRP system to an impure host language goes, either offering no interface to get the value of a behaviour (you might not need it at all), or only offering an interface to get the value at the present time, seems like the best way to go to me, for the reasons I outlined in my answer. The Conal link I gave was just for the semantic issue I touched on in the last paragraph; it doesn't contain any advice on this matter. – ehird Mar 07 '12 at 00:00
  • Ah ok. I'd forgotten that functions in Haskell are pure and this explains why these topics don't come up as much. I'm working on a Scala FRP framework so I think I will simply remove `at` and `transform` for the moment (externally that is). – seadowg Mar 07 '12 at 03:16