[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