[Haskell-cafe] Yampa vs. Reactive

Thomas Davie tom.davie at gmail.com
Fri Dec 19 04:45:10 EST 2008


Hi Henrik,

On 19 Dec 2008, at 02:05, Henrik Nilsson wrote:

> Hi Tom,
>
> > I'm not sure why mapping the function is not satisfactory -- It  
> would
> > create a new Behavior, who's internals contain only the two elements
> > from the list -- that would expose to the garbage collector that the
> > second element has no reference from this behavior any more, and  
> thus
> > the whole behavior could be collected.
>
> We must be talking at cross purposes here: there is no way that
> deleting the *output* from one of the behaviours from a list
> of outputs would cause the underlying behavior whose output no longer
> is observed to be garbage collected. After all, that list of
> three numbers is just a normal value: why should removing one of
> its elements, so to speak, affect the producer of the list?
>
> But if we have a list of running behaviors or signals, and that list
> is changed, then yes, of course we get the desired behavior (this
> is what Yampa does).
>
> So maybe that's what you mean?

I'm afraid not, rereading what I said, I really didn't explain what I  
was talking about well.  A Behavior in reactive is not just a  
continuous function of time.  It is a series of steps, each of which  
carries a function of time.  One such behavior might look like this:

(+5) -> 5 , (+6) -> 10 , integral

That is to say, this behavior starts off being a function that adds 5  
to the current time.  At 5 seconds, it steps, and the value changes to  
a function that adds 6 to time.  At this point, the function that adds  
5 to time can be garbage collected, along with the step.  At 10  
seconds, it becomes the integral of time, and the (+6) function, along  
with the next step is GCed.

To come back to your example, I'd expect the behavior to look like  
this (using named functions only so that I can refer to them):
i1 t = integral t
i2 t = integral (2 * t)
i3 t = integral (3 * t)
f t = [i1 t, i2 t, i3 t)]
g t = [i1 t, i3 t]
f -> 2, g

After 2 seconds, both f, and the first step may be garbage collected.   
As g does not have any reference to i2 t, it too can be garbage  
collected.

I hope that answers you more clearly.

> > That's a yes.  My first answer to how to implement the resetting
> > counter would be someting along the lines of this, but I'm not  
> certain > it's dead right:
> >
> > e = (1+) <$ mouseClick
> > e' = (const 0) <$ <some event>
> > b = accumB 0 (e `mappend` e')
> >
> > i.e. b is the behavior got by adding 1 every time the mouse click
> > event occurs, but resetting to 0 whenever <some event> occurs.
>
> Hmm. Looks somewhat complicated to me.
>
> Anyway, it doesn't really answer the fundamental question: how
> does one start a behavior/signal function at a particular point in  
> time?

In reactive, one doesn't.  All behaviors and events have the same  
absolute 0 value for time.

One can however simulate such a behavior, by using a `switcher`, or  
accumB.  In practice, having potentially large numbers of behaviors  
running but not changing until a certain event is hit is not a major  
problem.  This is not a problem because reactive knows that the  
current step contains a constant value, not a "real" function of time,  
because of this, no changes are pushed, and no work is done, until the  
event hits.

I believe Conal is however working on semantics for relative time  
based behaviors/events though.

Thanks

Tom Davie


More information about the Haskell-Cafe mailing list