[Haskell-cafe] Re: [reactive] FRP + physics / status of hpysics

Wolfgang Jeltsch g9ks157k at acme.softbase.org
Fri Mar 6 11:51:32 EST 2009


Am Freitag, 6. März 2009 14:34 schrieb Daniel Bünzli:
> > without using recursive signal functions,
>
> If this is because there's this limitation in the frp system you use

It is.

> then better fix the system.

The system is Grapefruit, by the way. And I’m its developer, by the way. :-)  
I have to say that it’s hard, if not impossible, to combine recursive signal 
definitions with other features, I want to have.

The point of recursive definitions is that you want to turn recursive 
equations from your problem domain directly into Haskell definitions. This is 
nice from a user’s point of view but hard from a programmers point of view. 
Standard Haskell already shows that. While it is possible to define an 
infinite list of ones by

    ones = 1 : ones,

it is not possible to do the same for sequences of type Seq. The above 
definition of ones relies very much on the structure of lists. Analogously, 
the ability to define signals recursively restricts the set of possible 
signal implementations seriously.

Haskell’s recursive definitions are very general. They have to find fixpoints 
of arbitrary functions over arbitrary type. Therefore, their semantics are 
rather weak. They give you the least defined fixpoint. The consequence is 
that you get bottom if you use something like

    x = 0 * x

although x = 0 might be what you prefered.

What I want to say is that coming up with a signal implementation that allows 
Haskell recursion and has other advantages at the same time is a big 
challenge. There are three features, you might want from a signal 
implementation:

    1. support for recursive signal definitions using Haskell equations

    2. memoization (for avoiding time leaks, for example)

    3. signals which may depend on external sources

I tried hard to support 2 and 3 well in Grapefruit. Fran has 1 but has 
problems with 2 and 3. I don’t know whether Reactive has a solution for 2 in 
the context of recursive definitions, i.e., whether the space and time leak 
problems of Fran were solved. I think, it has at least problems with 3.

For me, 2 and 3 are more important than 1. One reason is that 1 has other 
problems than being in conflict with 2 and 3. The result of a recursively 
defined signal depends on when sampling occurs. Since a recursive definition 
tends to result in accumulation of values, errors introduced by sampling may 
accumulate too. So you have to use clever approximation algorithms in 
addition.

My new idea is to view the problem in a different way. Let’s take the problem 
where the position of a ball is the integral of the difference between the 
mouse position and the ball position. As far as I can see, the transformation 
of the mouse position signal into the ball position signal forms a linear 
system. So the ball position signal is the mouse position signal convoluted 
with another signal.

If we would have a function that performes convolution, we could probably 
implement many problems using this function. Using convolution would let us 
get rid of the problems with accumulating errors.

I suppose that most of the recursive definitions you would use in FRP are 
differential or integral equations. Let’s look at the equation for the 
ball-following-the-mouse example:

    ballPos = integral (mousePos - ballPos)

ballPos can be represented in terms of mousePos as follows:

    ballPos = (exp . negate) * mousePos

where * means convolution. We could provide a library which supports common 
stuff like distance-dependent acceleration, friction etc.

Of course, you could say that now the programmer isn’t able anymore to enter 
his equations directly which isn’t nice. However, this situation is not 
different to other areas. For example, you cannot write

    x = 5 - x / 2

and expect x to be 10 / 3. Instead, you have to transform the equation first.

> Soon or later it you'll want it elsewhere. A recursive reactive signal just
> means that some of what your reactive program computed will be
> usefull/necessary for the next step.

You can do this with convolution, I think.

By the way, continuous signals don’t have steps. These are just introduced by 
sampling.

> You'll see that happen very quickly (e.g. any simple reactive state
> machine).

“State machine” sounds like a discrete problem. You can use accumulation over 
event sequences here (as, for example, provided by the scan function in 
FRP.Grapefruit.Signal.Discrete).

By the way, the adress of the Grapefruit mailing list is 
grapefruit at projects.haskell.org, not grapefruit at haskell.org.

Best wishes,
Wolfgang


More information about the Haskell-Cafe mailing list