I think what you&#39;re describing results from a worst-case combination of three factors:<br><br>1. Infinitesimal delay semantics of switch<br>2. Euler integration<br>3. Exact synchronization of numerical integration time samples with display samples<br>


<br> Of these three factors, I see the first one as benign and semantically ideal.  The imposed delay is the theoretical
minimum (infinitesimal) while still allowing meaningful specification
of self-reactive and mutually-reactive systems.  And it&#39;s consistent
with differentially specified continuous behavior.  On the other hand,
the second and third factors are implementation artifacts rather than
desirable semantics.  Moreover, they&#39;re artifacts that cause the
implementation to stray from the semantic ideal.<br>
<br>My inclination is to embrace 1 and somehow fix 2 &amp; 3.  I&#39;m guessing 3 is easy and 2 is hard.<br><br>For
3, I know of no benefit to having integration sample times correspond
to display times, or even to match the frequency.  I implemented it
that way just for simplicity, and now I see it was a terrible idea.  My
intention is to use a variable-step-size method that adapts to both the
nature of the behavior being integrated and to the available compute
cycles.<br>
<br>As for 2, I&#39;ve used much better integration methods in the past. 
What&#39;s tricky here is getting an integration method that works for
self- or mutully-recursive integration (i.e. ODE systems) *without* the
ability to see the cycles.  Euler is easy but is terribly inaccurate or
inefficient&amp;instable.<br>
<br>  - Conal<br><br><div class="gmail_quote">2009/7/7 Patai Gergely <span dir="ltr">&lt;<a href="mailto:patai_gergely@fastmail.fm">patai_gergely@fastmail.fm</a>&gt;</span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Hello all,<br>
<br>
I opened a thread some time ago where I asked whether it&#39;s enough to<br>
have only immediate switching. But it dawned on me that Reactive<br>
switches are actually all delayed, since even though the delay is<br>
infinitesimal in principle, we still have to wait for the next point of<br>
observation until we can see its effect. This is a huge problem in<br>
practice, because this way every stateful signal imposes a delay equal<br>
to the length of the period between observations. Here&#39;s a simple test<br>
case for illustration:<br>
<br>
&gt; import Control.Applicative<br>
&gt; import FRP.Reactive<br>
&gt;<br>
&gt; tick :: Event ()<br>
&gt; tick = atTimes [0..]<br>
&gt;<br>
&gt; behs :: [Behavior Double]<br>
&gt; behs = pure 1 : map (integral tick) behs<br>
&gt;<br>
&gt; eventList :: Event a -&gt; [a]<br>
&gt; eventList e = x : eventList e&#39;<br>
&gt;     where (x,e&#39;) = firstRestE e<br>
&gt;<br>
&gt; testBeh :: Behavior a -&gt; [a]<br>
&gt; testBeh b = take 10 $ eventList (snapshot_ b tick)<br>
&gt;<br>
&gt; test :: IO ()<br>
&gt; test = mapM_ (print . testBeh) (take 5 behs)<br>
<br>
Running test prints the following:<br>
<br>
[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]<br>
[0.0,0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0]<br>
[0.0,0.0,0.0,1.0,3.0,6.0,10.0,15.0,21.0,28.0]<br>
[0.0,0.0,0.0,0.0,1.0,4.0,10.0,20.0,35.0,56.0]<br>
[0.0,0.0,0.0,0.0,0.0,1.0,5.0,15.0,35.0,70.0]<br>
<br>
I ran into the very same problem when working on the first version of<br>
Elerea. Transfer functions in version 0.1.0 behave exactly the same way,<br>
and I switched to immediate transfer functions from 0.2.0. The<br>
difference is obvious if you look at the breakout example in action: in<br>
0.1.0, the ball takes long to react to collisions, since the dependency<br>
cycle consists of three items (bricks, velocity, position), so any<br>
change takes just as many frames to propagate. From 0.2.0 onwards,<br>
collisions are much more accurate without any change in the example<br>
code.<br>
<br>
Sure, it is possible to work around the delay by combining the switching<br>
value with the one that caused its switch, but this adds a lot of<br>
complexity to the code on the user end. You can make life easier by<br>
introducing immediate versions as helper functions, but then you just<br>
reintroduced this distinction. Of course this is not surprising, since<br>
neither delayed nor immediate switching is sufficient on its own. But<br>
this means that Reactive should support both out of the box and not<br>
encourage ad hoc workarounds that are likely to break in unexpected<br>
ways. Also, immediate switching seems the more sensible default, because<br>
it&#39;s more straightforward to derive the delayed version from it than the<br>
other way around, and it is what we need most of the time.<br>
<br>
Are there any plans to address this problem? Or a completely new angle<br>
to look at it from?<br>
<br>
Gergely<br>
<font color="#888888"><br>
--<br>
<a href="http://www.fastmail.fm" target="_blank">http://www.fastmail.fm</a> - Faster than the air-speed velocity of an<br>
                          unladen european swallow<br>
<br>
_______________________________________________<br>
Reactive mailing list<br>
<a href="mailto:Reactive@haskell.org">Reactive@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/reactive" target="_blank">http://www.haskell.org/mailman/listinfo/reactive</a><br>
</font></blockquote></div><br>