apfelmus at quantentunnel.de
Tue Oct 16 10:20:47 CEST 2012
sorry for the late reply, I have been traveling in the last weeks.
Miguel Negrao wrote:
> Heinrich Apfelmus escreveu:
>> Miguel Negrao wrote:
>>> Thanks for the explanation. I was wondering, how would one translate
>>> this Yampa code into reactive-banana:
>>> fallingBall :: Pos -> Vel -> SF () (Pos, Vel)
>>> fallingBall y0 v0 = proc () -> do
>>> v <- (v0 +) ˆ<< integral -< -9.81
>>> y <- (y0 +) ˆ<< integral -< v
>>> returnA -< (y, v)
>>> fallingBall’ :: Pos -> Vel -> SF () ((Pos,Vel), Event (Pos,Vel))
>>> fallingBall’ y0 v0 = proc () -> do
>>> yv@(y, _) <- fallingBall y0 v0 -< ()
>>> hit <- edge -< y <= 0
>>> returnA -< (yv, hit ‘tag‘ yv)
>>> bouncingBall :: Pos -> SF () (Pos, Vel)
>>> bouncingBall y0 = bbAux y0 0.0
>>> bbAux y0 v0 = switch (fallingBall’ y0 v0) $ \(y,v) -> bbAux y (-v)
> Yes, looking at the internals of Yampa I had seen that they have
> internal time management, but my question was more specifically if there
> was a way to have a function like bbAux which recursively switches into
> itself. Would it be possible with the new dynamic switching ? I find
> that way of expressing the discontinuous changes quite elegant.
Yes, it's possible, but it will feel alien. There are two reasons for that:
1. switchB is meant to change the behavior whenever the event occurs,
not just on the first occurrence. The bbAux function is recursive
precisely because only the first occurrence causes a switch in Yampa.
Maybe reactive-banana should adopt this approach as well, but I'm
2. In Yampa, fallingBall is a signal function, which means that it has
no fixed starting time. In contrast, behaviors in reactive-banana
usually have a fixed starting time so that they can accumulate state. Of
course, reactive-banana also has behaviors that have a variable starting
time, but they are a separate type. In other words, you have to model it as
fallingBall :: Pos -> Vel -> AnyMoment Behavior Pos
So, modeling this using dynamic event switching is possible, but these
two points mean that it's probably much easier to use a recursive
event/behavior combination like in the Animation.hs example or Andreas
Bernstein's breakout code.
As you can see, dynamic event switching is still uncharted territory,
there are a lot of design patterns to discover.
> more elegant seems to be the instantaneous impulses (modeling of
> distributions or dirac deltas) although I couldn’t find any functioning
> code that implements it .
Well, I do not think that mixing continuous signals and discrete events
in this way is a good idea. Having two separate types gives you more
information to reason with: Event can only be discrete, Behavior can
only be continuous.
I would like to stress again that the design space for FRP is huge,
which is good. But the ultimate goal is to simplify a certain class of
code, namely GUIs, audio and games, and I feel that few, if any FRP
approaches have been tested enough against these "hard" targets. I mean,
if I use FRP to implement a game and the code is just as messy as the
imperative version, then I may wonder why I am doing this at all. So
far, I only know of Conal who makes a convincing argument for his style
Conal Elliott. Declarative Event-Oriented Programming.
(Interestingly, he doesn't really use dynamic event switching in this
Simplicity also hinges on a lot of details, see for instance my
discussion on GUI elements
Conal's decision to allow recursion between Event and Behavior is one of
these very important details.
More information about the Beginners