<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Simply efficient functional reactivity</title>
	<atom:link href="http://conal.net/blog/posts/simply-efficient-functional-reactivity/feed/" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/</link>
	<description>Inspirations &#38; experiments, mainly about denotational programming in Haskell</description>
	<lastBuildDate>Tue, 16 Mar 2010 20:14:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-23408</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Tue, 30 Jun 2009 18:52:17 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-23408</guid>
		<description>&lt;p&gt;Hi Ivan.  I don&#039;t have easy access to the detailed differences.  There was very little change (lots of revision already). Mainly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplified the definition of &lt;code&gt;joinE&lt;/code&gt; in 7.2.2&lt;/li&gt;
&lt;li&gt;Simplified (a bit) the &lt;code&gt;unamb&lt;/code&gt; &quot;reference implementation&quot; in Figure 4, noting that it is not an efficient implementation.&lt;/li&gt;
&lt;/ul&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Ivan.  I don&#8217;t have easy access to the detailed differences.  There was very little change (lots of revision already). Mainly:</p>

<ul>
<li>Simplified the definition of <code>joinE</code> in 7.2.2</li>
<li>Simplified (a bit) the <code>unamb</code> &#8220;reference implementation&#8221; in Figure 4, noting that it is not an efficient implementation.</li>
</ul>]]></content:encoded>
	</item>
	<item>
		<title>By: ivan</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-23400</link>
		<dc:creator>ivan</dc:creator>
		<pubDate>Tue, 30 Jun 2009 15:57:18 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-23400</guid>
		<description>&lt;p&gt;Could you post a changelog between the most recent version of this paper and the new push-pull functional reactive programming paper, please?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Could you post a changelog between the most recent version of this paper and the new push-pull functional reactive programming paper, please?</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Conal Elliott &#187; Blog Archive &#187; Why classic FRP does not fit interactive behavior</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-12531</link>
		<dc:creator>Conal Elliott &#187; Blog Archive &#187; Why classic FRP does not fit interactive behavior</dc:creator>
		<pubDate>Wed, 10 Dec 2008 06:45:54 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-12531</guid>
		<description>&lt;p&gt;[...] The Arrow style required multiple behaviors to be bunched up into one. That combination appears to thwart efficient, change-driven evaluation, which was the problem I tackled in Simply efficient functional reactivity. [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] The Arrow style required multiple behaviors to be bunched up into one. That combination appears to thwart efficient, change-driven evaluation, which was the problem I tackled in Simply efficient functional reactivity. [...]</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Max</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-8535</link>
		<dc:creator>Max</dc:creator>
		<pubDate>Sat, 30 Aug 2008 09:37:57 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-8535</guid>
		<description>&lt;p&gt;So, when are you going to release the library that goes with this paper? I&#039;m really looking forward to playing around with this stuff!&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>So, when are you going to release the library that goes with this paper? I&#8217;m really looking forward to playing around with this stuff!</p>]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-5569</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Wed, 07 May 2008 17:23:23 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-5569</guid>
		<description>&lt;p&gt;Thanks, Jake!  There were two mistakes.  Errata and paper source updated.  Here&#039;s the correct code:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;joinR &lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;a `Stepper` Ev ur&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; `Stepper` Ev urr&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; =
  a `stepper` Ev u
 &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;where&lt;/span&gt;
   u = &lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;`switcher` Ev urr&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; &lt;$&gt; ur&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; `&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;mappend&lt;/span&gt;&lt;/a&gt;` &lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;join &lt;$&gt; urr&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Thanks, Jake!  There were two mistakes.  Errata and paper source updated.  Here&#8217;s the correct code:</p>

<p><div>
<pre class="haskell">joinR <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a `Stepper` Ev ur<span style="color: green;">&#41;</span> `Stepper` Ev urr<span style="color: green;">&#41;</span> =
  a `stepper` Ev u
 <span style="color: #050; font-weight: bold;">where</span>
   u = <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>`switcher` Ev urr<span style="color: green;">&#41;</span> &lt;$&gt; ur<span style="color: green;">&#41;</span> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#v:mappend" rel="nofollow"><span style="font-weight: bold;">mappend</span></a>` <span style="color: green;">&#40;</span>join &lt;$&gt; urr<span style="color: green;">&#41;</span></pre>
</div></p>]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-5567</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Wed, 07 May 2008 16:32:44 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-5567</guid>
		<description>&lt;p&gt;I discovered an error on page 8. Your definition of joinR:&lt;/p&gt;

&lt;pre&gt;
joinR :: Reactive (Reactive a) -&gt; Reactive a
joinR :: ((a `Stepper` Ev ur) `Stepper` Ev urr) =
         a `Stepper` Ev u
     where u = ((`switcher` e&#039;)  ur) `mappend` (join  urr)
&lt;/pre&gt;

&lt;p&gt;Before completing the definition of &lt;code&gt;u&lt;/code&gt;, you say that it is the first of either &lt;code&gt;(`switcher` Ev ur) &lt;$&gt; ur&lt;/code&gt; or &lt;code&gt;join  urr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In actual definition of &lt;code&gt;u&lt;/code&gt; in your paper, you use &lt;code&gt;e&#039;&lt;/code&gt;, which was never bound. I believe &lt;code&gt;e&#039;&lt;/code&gt; is supposed to be &lt;code&gt;Ev urr&lt;/code&gt;. Before completing the definition of &lt;code&gt;u&lt;/code&gt;, your intermediate code (&lt;code&gt;(`switcher` Ev ur) &lt;$&gt; ur&lt;/code&gt;) uses neither &lt;code&gt;e&#039;&lt;/code&gt; nor &lt;code&gt;Ev urr&lt;/code&gt;, but uses &lt;code&gt;Ev ur&lt;/code&gt; instead.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I discovered an error on page 8. Your definition of joinR:</p>

<pre>
joinR :: Reactive (Reactive a) -&gt; Reactive a
joinR :: ((a `Stepper` Ev ur) `Stepper` Ev urr) =
         a `Stepper` Ev u
     where u = ((`switcher` e')  ur) `mappend` (join  urr)
</pre>

<p>Before completing the definition of <code>u</code>, you say that it is the first of either <code>(`switcher` Ev ur) &lt;$&gt; ur</code> or <code>join  urr</code>.</p>

<p>In actual definition of <code>u</code> in your paper, you use <code>e'</code>, which was never bound. I believe <code>e'</code> is supposed to be <code>Ev urr</code>. Before completing the definition of <code>u</code>, your intermediate code (<code>(`switcher` Ev ur) &lt;$&gt; ur</code>) uses neither <code>e'</code> nor <code>Ev urr</code>, but uses <code>Ev ur</code> instead.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4148</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Wed, 30 Apr 2008 19:13:34 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4148</guid>
		<description>&lt;p&gt;Hi Josef,&lt;/p&gt;

&lt;p&gt;I started out with that simpler definition.  Here&#039;s what I think is a problem with it: Concurrent Haskell has no atomic operation for reading an &lt;code&gt;MVar&lt;/code&gt;.  The &lt;code&gt;readMVar&lt;/code&gt; action instead does a &lt;code&gt;takeMVar&lt;/code&gt; followed by a &lt;code&gt;putMVar&lt;/code&gt;.  After the reader&#039;s &lt;code&gt;takeMVar&lt;/code&gt; and before its &lt;code&gt;putMVar&lt;/code&gt;, the race-loser could unblock and do its &lt;code&gt;putMVar&lt;/code&gt;.  This second &lt;code&gt;putMVar&lt;/code&gt; to the same &lt;code&gt;MVar&lt;/code&gt; would break the pure semantics &lt;em&gt;and&lt;/em&gt; would cause the reader to block instead of completing its &lt;code&gt;readMVar&lt;/code&gt;. I hadn&#039;t considered this possibility until Ivan Tomac pointed it out.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Josef,</p>

<p>I started out with that simpler definition.  Here&#8217;s what I think is a problem with it: Concurrent Haskell has no atomic operation for reading an <code>MVar</code>.  The <code>readMVar</code> action instead does a <code>takeMVar</code> followed by a <code>putMVar</code>.  After the reader&#8217;s <code>takeMVar</code> and before its <code>putMVar</code>, the race-loser could unblock and do its <code>putMVar</code>.  This second <code>putMVar</code> to the same <code>MVar</code> would break the pure semantics <em>and</em> would cause the reader to block instead of completing its <code>readMVar</code>. I hadn&#8217;t considered this possibility until Ivan Tomac pointed it out.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Josef Svenningsson</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4108</link>
		<dc:creator>Josef Svenningsson</dc:creator>
		<pubDate>Wed, 30 Apr 2008 15:57:50 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4108</guid>
		<description>&lt;p&gt;I have a very small question about the race function defined at the end of the paper. Is the lock MVar really necessary? I think not but maybe I&#039;m just missing something. In the run function couldn&#039;t you just write to the v MVar first and then kill the other thread. Then double kill will be prevented because the other thread will block when trying to assing to the MVar and will never reach the killThread before being killed himself.&lt;/p&gt;

&lt;pre&gt;
a `race` b =
  do  v &lt;- newEmptyMVar
      let run io tid = forkIO $ do x &lt;- io
                                   putMVar v x
                                   killThread tid
      mdo ta &lt;- run a tb
          tb &lt;- run b ta
      readMVar v&lt;/pre&gt;

&lt;p&gt;Well, maybe this issue is moot anyway since you and Ryan Ingram seem to have come up with some nicer way of doing this.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I have a very small question about the race function defined at the end of the paper. Is the lock MVar really necessary? I think not but maybe I&#8217;m just missing something. In the run function couldn&#8217;t you just write to the v MVar first and then kill the other thread. Then double kill will be prevented because the other thread will block when trying to assing to the MVar and will never reach the killThread before being killed himself.</p>

<pre>
a `race` b =
  do  v &lt;- newEmptyMVar
      let run io tid = forkIO $ do x &lt;- io
                                   putMVar v x
                                   killThread tid
      mdo ta &lt;- run a tb
          tb &lt;- run b ta
      readMVar v</pre>

<p>Well, maybe this issue is moot anyway since you and Ryan Ingram seem to have come up with some nicer way of doing this.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4043</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Tue, 29 Apr 2008 23:29:05 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4043</guid>
		<description>&lt;p&gt;Ryan: I see what you mean, now.  I think the following two special cases fix this problem, inserted before the one in the paper (quoted in your most recent comment):&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;Future &lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;Max MaxBound,_&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; `mergeu` v = v
u `mergeu` Future &lt;span style=&quot;color: green;&quot;&gt;&#40;&lt;/span&gt;Max MaxBound,_&lt;span style=&quot;color: green;&quot;&gt;&#41;&lt;/span&gt; = u&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;I just added these lines to the implementation.  Thanks for pointing out the leak.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Ryan: I see what you mean, now.  I think the following two special cases fix this problem, inserted before the one in the paper (quoted in your most recent comment):</p>

<p><div>
<pre class="haskell">Future <span style="color: green;">&#40;</span>Max MaxBound,_<span style="color: green;">&#41;</span> `mergeu` v = v
u `mergeu` Future <span style="color: green;">&#40;</span>Max MaxBound,_<span style="color: green;">&#41;</span> = u</pre>
</div></p>

<p>I just added these lines to the implementation.  Thanks for pointing out the leak.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Ingram</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4040</link>
		<dc:creator>Ryan Ingram</dc:creator>
		<pubDate>Tue, 29 Apr 2008 22:23:20 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4040</guid>
		<description>&lt;p&gt;For (2), yes.  I found it very interesting that given the interface to future could be that minimal (four small typeclasses &amp; two or three additional operations) and all of the &quot;definition&quot;-side of behavior/reactive/event could be specified in terms of that minimal interface.&lt;/p&gt;

&lt;p&gt;Of course you need to plumb into the implementation details when you are writing the interpretation functions (occs/sinkE/sinkR), unless you take waitFor and force as primitive as well, which severely constrains the design of Future.  But most client code can absolutely ignore that and use the behavior/reactive/event abstraction.&lt;/p&gt;

&lt;p&gt;(3) From your definition of mappend on events:&lt;/p&gt;

&lt;pre&gt;
u `mergeu` v = (inFutR (`merge` v) &lt;$&gt; u)
           &lt;+&gt; (inFutR (u `merge`) &lt;$&gt; v)
   where
       inFutR f (r `Stepper` Ev u0) = r `Stepper` Ev (f u0)
&lt;/pre&gt;

&lt;p&gt;Consider the case where v = never.  The rhs of &lt;+&gt; goes away, but we still call &quot;merge&quot; in the lhs, and pass v again.  So any storage held by v cannot be reclaimed, and there&#039;s also a time leak as &lt;+&gt; keeps getting called needlessly.&lt;/p&gt;

&lt;p&gt;The more merges that happen, the worse the leak gets.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>For (2), yes.  I found it very interesting that given the interface to future could be that minimal (four small typeclasses &amp; two or three additional operations) and all of the &#8220;definition&#8221;-side of behavior/reactive/event could be specified in terms of that minimal interface.</p>

<p>Of course you need to plumb into the implementation details when you are writing the interpretation functions (occs/sinkE/sinkR), unless you take waitFor and force as primitive as well, which severely constrains the design of Future.  But most client code can absolutely ignore that and use the behavior/reactive/event abstraction.</p>

<p>(3) From your definition of mappend on events:</p>

<pre>
u `mergeu` v = (inFutR (`merge` v) &lt;$&gt; u)
           &lt;+&gt; (inFutR (u `merge`) &lt;$&gt; v)
   where
       inFutR f (r `Stepper` Ev u0) = r `Stepper` Ev (f u0)
</pre>

<p>Consider the case where v = never.  The rhs of &lt;+&gt; goes away, but we still call &#8220;merge&#8221; in the lhs, and pass v again.  So any storage held by v cannot be reclaimed, and there&#8217;s also a time leak as &lt;+&gt; keeps getting called needlessly.</p>

<p>The more merges that happen, the worse the leak gets.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4036</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Tue, 29 Apr 2008 19:37:44 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4036</guid>
		<description>&lt;p&gt;Hi Ryan.  Thanks for the additional comments.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;(1) You&#039;ve lost the &quot;edge&quot; constructors for events &lt;em&gt;[...]&lt;/em&gt;  You can implement them for Reactive instead of Behavior, but it&#039;s impossible to do so for Behavior itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agreed, given that a behavior can be any (computable) function of time and the semantics of the edge operations require capturing every transition and capturing it exactly.  There are some variations on the &lt;code&gt;Behavior&lt;/code&gt; type, such as derivative bounds, that would allow catching each transition, while retaining continuous time.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I think it&#039;s possible to implement this less powerful operation &lt;em&gt;[...]&lt;/em&gt;
  which filters the &quot;tick&quot; event list to only contain occurrences where the behavior changed from False to True between one tick and the next.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don&#039;t know where the idea of a &quot;tick&quot; could fit in FRP&#039;s continuous-time semantics.  Perhaps you&#039;re thinking of a temporally discrete variation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;(2) The entire reactive system can be parametrized on the definition of Future; futures need the following operations: &lt;em&gt;[...]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I may be missing your point.  Are you saying that futures are only used through the Future interface?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;(3) merging event streams leaks memory &lt;em&gt;[...]&lt;/em&gt; Once a connection is closed, it can&#039;t possibly give any more events, but the event merge listens to it forever.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why do you expect event merge (&lt;code&gt;mappend&lt;/code&gt;) to keep listening to an event that knowably cannot have any more occurrences?  An event is represented as a future, and that future can have an explicitly infinite (&lt;code&gt;MaxBound&lt;/code&gt;) time.  (See Section 4.5 and Figure 1.)  Since &lt;code&gt;mappend&lt;/code&gt; on events works via &lt;code&gt;mappend&lt;/code&gt; on futures, and the latter handles infinite time, I think your example would work out easily enough without a space leak, assuming that the event reflects the closed connection with an infinite-time future (analogous to a nil at the end of a list).&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Ryan.  Thanks for the additional comments.</p>

<blockquote>
  <p>(1) You&#8217;ve lost the &#8220;edge&#8221; constructors for events <em>[...]</em>  You can implement them for Reactive instead of Behavior, but it&#8217;s impossible to do so for Behavior itself.</p>
</blockquote>

<p>Agreed, given that a behavior can be any (computable) function of time and the semantics of the edge operations require capturing every transition and capturing it exactly.  There are some variations on the <code>Behavior</code> type, such as derivative bounds, that would allow catching each transition, while retaining continuous time.</p>

<blockquote>
  <p>I think it&#8217;s possible to implement this less powerful operation <em>[...]</em>
  which filters the &#8220;tick&#8221; event list to only contain occurrences where the behavior changed from False to True between one tick and the next.</p>
</blockquote>

<p>I don&#8217;t know where the idea of a &#8220;tick&#8221; could fit in FRP&#8217;s continuous-time semantics.  Perhaps you&#8217;re thinking of a temporally discrete variation.</p>

<blockquote>
  <p>(2) The entire reactive system can be parametrized on the definition of Future; futures need the following operations: <em>[...]</em></p>
</blockquote>

<p>I may be missing your point.  Are you saying that futures are only used through the Future interface?</p>

<blockquote>
  <p>(3) merging event streams leaks memory <em>[...]</em> Once a connection is closed, it can&#8217;t possibly give any more events, but the event merge listens to it forever.</p>
</blockquote>

<p>Why do you expect event merge (<code>mappend</code>) to keep listening to an event that knowably cannot have any more occurrences?  An event is represented as a future, and that future can have an explicitly infinite (<code>MaxBound</code>) time.  (See Section 4.5 and Figure 1.)  Since <code>mappend</code> on events works via <code>mappend</code> on futures, and the latter handles infinite time, I think your example would work out easily enough without a space leak, assuming that the event reflects the closed connection with an infinite-time future (analogous to a nil at the end of a list).</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Ingram</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4035</link>
		<dc:creator>Ryan Ingram</dc:creator>
		<pubDate>Tue, 29 Apr 2008 19:12:43 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4035</guid>
		<description>&lt;p&gt;I knew I forgot something...&lt;/p&gt;

&lt;p&gt;(3) merging event streams leaks memory; consider a long-running server application of this type:&lt;/p&gt;

&lt;pre&gt;
type Connection = (Event Char, Char -&gt; IO ()) -- TCP
listen :: Int -&gt; IO (Event Connection) -- listen on a TCP port
server :: Event Connection -&gt; Event (IO ()) -- server actions
&lt;/pre&gt;

&lt;p&gt;Somewhere inside of &quot;server&quot; there would be an event join which allows the server to extract data from a connection; this eventually results in an mappend between a future connection and a future character from a connection.  Once a connection is closed, it can&#039;t possibly give any more events, but the event merge listens to it forever.&lt;/p&gt;

&lt;p&gt;This can be solved with this additional operation on futures:&lt;/p&gt;

&lt;pre&gt;
whenNever :: Future t a -&gt; Future t b -&gt; Future t b
-- semantics:
-- whenNever never f = f
-- whenNever _     _ = never

mergeE :: Event a -&gt; Event a -&gt; Event a
mergeE (Ev e1) (Ev e2) = Ev $
    -- if e2 is &quot;never&quot;, throw it away
    whenNever e2 e1
    -- if e1 is &quot;never&quot;, throw it away
    `mappend` whenNever e1 e2
    -- if e1 arrives first, use it
    `mappend` fmap (\(Stepper a e1&#039;) -&gt; Stepper a $ mergeE e1&#039; (Ev e2)) e1
    -- otherwise use e2
    `mappend` fmap (\(Stepper a e2&#039;) -&gt; Stepper a $ mergeE (Ev e1) e2&#039;) e2
&lt;/pre&gt;

&lt;p&gt;Implementing whenNever is tricky, though.  The best I&#039;ve done so far is have an explicit representation for futures that are Never; another option is to dynamically allow a future to become &quot;Never&quot; although that could break the axioms of futures.  The best solution, I think, is to have whenNever delay the second future to the point at which we can determine the first future is never; if it&#039;s immediately obvious (&quot;pure&quot; never) we can return f directly, otherwise we may delay f&#039;s occurrence.  This doesn&#039;t break mergeE at all, but it does complicate the semantics of whenNever.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I knew I forgot something&#8230;</p>

<p>(3) merging event streams leaks memory; consider a long-running server application of this type:</p>

<pre>
type Connection = (Event Char, Char -&gt; IO ()) -- TCP
listen :: Int -&gt; IO (Event Connection) -- listen on a TCP port
server :: Event Connection -&gt; Event (IO ()) -- server actions
</pre>

<p>Somewhere inside of &#8220;server&#8221; there would be an event join which allows the server to extract data from a connection; this eventually results in an mappend between a future connection and a future character from a connection.  Once a connection is closed, it can&#8217;t possibly give any more events, but the event merge listens to it forever.</p>

<p>This can be solved with this additional operation on futures:</p>

<pre>
whenNever :: Future t a -&gt; Future t b -&gt; Future t b
-- semantics:
-- whenNever never f = f
-- whenNever _     _ = never

mergeE :: Event a -&gt; Event a -&gt; Event a
mergeE (Ev e1) (Ev e2) = Ev $
    -- if e2 is "never", throw it away
    whenNever e2 e1
    -- if e1 is "never", throw it away
    `mappend` whenNever e1 e2
    -- if e1 arrives first, use it
    `mappend` fmap (\(Stepper a e1') -&gt; Stepper a $ mergeE e1' (Ev e2)) e1
    -- otherwise use e2
    `mappend` fmap (\(Stepper a e2') -&gt; Stepper a $ mergeE (Ev e1) e2') e2
</pre>

<p>Implementing whenNever is tricky, though.  The best I&#8217;ve done so far is have an explicit representation for futures that are Never; another option is to dynamically allow a future to become &#8220;Never&#8221; although that could break the axioms of futures.  The best solution, I think, is to have whenNever delay the second future to the point at which we can determine the first future is never; if it&#8217;s immediately obvious (&#8220;pure&#8221; never) we can return f directly, otherwise we may delay f&#8217;s occurrence.  This doesn&#8217;t break mergeE at all, but it does complicate the semantics of whenNever.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Ingram</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-4034</link>
		<dc:creator>Ryan Ingram</dc:creator>
		<pubDate>Tue, 29 Apr 2008 18:58:17 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-4034</guid>
		<description>&lt;p&gt;OK, now that I&#039;ve played with this for a while I have a few real comments about the paper:&lt;/p&gt;

&lt;p&gt;(1) You&#039;ve lost the &quot;edge&quot; constructors for events:&lt;/p&gt;

&lt;pre&gt;
risingEdge :: Behavior Bool -&gt; Event ()
fallingEdge :: Behavior Bool -&gt; Event ()
&lt;/pre&gt;

&lt;p&gt;You can implement them for Reactive instead of Behavior, but it&#039;s impossible to do so for Behavior itself.  That said, maybe that&#039;s a good thing; they can&#039;t possibly detect the exact edge in any system that lets you define behaviors with fmap or arr.  I think it&#039;s possible to implement this less powerful operation:&lt;/p&gt;

&lt;pre&gt;
risingEdgeAcrossTick :: Behavior Bool -&gt; Event () -&gt; Event ()
risingEdgeAcrossTick beh tick = ...
&lt;/pre&gt;

&lt;p&gt;which filters the &quot;tick&quot; event list to only contain occurrences where the behavior changed from False to True between one tick and the next.&lt;/p&gt;

&lt;p&gt;(2) The entire reactive system can be parametrized on the definition of Future; futures need the following operations:&lt;/p&gt;

&lt;pre&gt;
type Future t a -- abstract, although assume Eq t, Ord t, Bounded t

-- given the semantics from the paper
instance Functor (Future t)
instance Applicative (Future t)
instance Monad (Future t)
instance Monoid (Future t a) -- mappend = firstFuture, mempty = never
instance MonadPlus (Future t) -- see Monoid

-- plus these additional two operations:
exactly :: t -&gt; a -&gt; Future t a
   -- force (exactly t a) = (t, a)

withTime :: Future t a -&gt; Future t (t,a)
   -- force (withTime f) = withTimeSem (force f) where
   --    withTimeSem (t,a) = (t, (t,a))
&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p>OK, now that I&#8217;ve played with this for a while I have a few real comments about the paper:</p>

<p>(1) You&#8217;ve lost the &#8220;edge&#8221; constructors for events:</p>

<pre>
risingEdge :: Behavior Bool -&gt; Event ()
fallingEdge :: Behavior Bool -&gt; Event ()
</pre>

<p>You can implement them for Reactive instead of Behavior, but it&#8217;s impossible to do so for Behavior itself.  That said, maybe that&#8217;s a good thing; they can&#8217;t possibly detect the exact edge in any system that lets you define behaviors with fmap or arr.  I think it&#8217;s possible to implement this less powerful operation:</p>

<pre>
risingEdgeAcrossTick :: Behavior Bool -&gt; Event () -&gt; Event ()
risingEdgeAcrossTick beh tick = ...
</pre>

<p>which filters the &#8220;tick&#8221; event list to only contain occurrences where the behavior changed from False to True between one tick and the next.</p>

<p>(2) The entire reactive system can be parametrized on the definition of Future; futures need the following operations:</p>

<pre>
type Future t a -- abstract, although assume Eq t, Ord t, Bounded t

-- given the semantics from the paper
instance Functor (Future t)
instance Applicative (Future t)
instance Monad (Future t)
instance Monoid (Future t a) -- mappend = firstFuture, mempty = never
instance MonadPlus (Future t) -- see Monoid

-- plus these additional two operations:
exactly :: t -&gt; a -&gt; Future t a
   -- force (exactly t a) = (t, a)

withTime :: Future t a -&gt; Future t (t,a)
   -- force (withTime f) = withTimeSem (force f) where
   --    withTimeSem (t,a) = (t, (t,a))
</pre>]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Ingram</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-3893</link>
		<dc:creator>Ryan Ingram</dc:creator>
		<pubDate>Wed, 23 Apr 2008 01:10:27 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-3893</guid>
		<description>&lt;p&gt;Hi Conal, hopefully I can answer your questions satisfactorily.&lt;/p&gt;

&lt;p&gt;(1) Absolutely: that was the goal.  In particular, here is the implementation of &quot;force&quot;:&lt;/p&gt;

&lt;pre&gt;
type FTime t = AddBounds t
type F t a = (FTime t, a)
force :: Future t a -&gt; F t a
force f = unsafePerformIO $ allowNestedTransactions $
             atomically $ value f
&lt;/pre&gt;

&lt;p&gt;allowNestedTransactions is a hack I came up with to do, well, what its name says:&lt;/p&gt;

&lt;pre&gt;
allowNestedTransactions m = do
    v &lt;- newEmptyMVar
    forkIO (m &gt;&gt;= putMVar v)
    takeMVar v
&lt;/pre&gt;

&lt;p&gt;This uses a separate thread to trick the STM runtime into allowing a nested transaction, but the behavior is exactly that of a single-threaded program; the MVar handles control flow and makes sure that the originating thread blocks until the computation on the forked thread completes.  Ideally this won&#039;t be necessary in a future implementation of STM.  Of course this is only required if &quot;force x&quot; is used as a pure value inside another STM computation, and none of the reactive code calls force except for &quot;occs&quot;.  But pure values should act like pure values, so something was required.&lt;/p&gt;

&lt;p&gt;(2) Exactly; here are the requirements for a correct future:
If f denotes (t0, a), then:&lt;/p&gt;

&lt;pre&gt;
waitFor f t ~&gt; return ()
  =&gt; forall (s &lt;= t). waitFor f s ~&gt; return ()
-- That is, if waitFor f t doesn&#039;t retry, then waitFor f t
--   doesn&#039;t retry for earlier t either.

waitFor f t &gt;&gt; maybeSTM (value f) ~&gt; return Nothing
   =&gt; t0 &gt; t
-- That is, if waitFor f t doesn&#039;t retry, and value f
--  does, then f is not yet available at time t.
&lt;/pre&gt;

&lt;p&gt;Another way to look at it is to treat each future as having a universe which has its own current time.  Then we have the following rules:&lt;/p&gt;

&lt;pre&gt;
now :: Future a -&gt; STM Time -- never retries

waitFor f t = do
    n &lt;- now f
    if (t &lt;= n) then return () else retry
-- In fact, I define &quot;now&quot; for a future as &quot;the largest t
--   such that waitFor f t does not retry&quot;

value f = do
    n &lt;- now f
    if (n &gt;= t0) -- this is the t0 from the denotation of the future
      then return (t0, a)
      else retry

now (pure x) = return maxBound
now (firstFuture f1 f2) = min &lt;$&gt; now f1 &lt;*&gt; now f2
&lt;/pre&gt;

&lt;p&gt;So, in &quot;firstFuture&quot;, this code snippet:&lt;/p&gt;

&lt;pre&gt;
        (Just (t1, v1), Nothing) -&gt; do
            waitFor f2 t1
            return (t1, v1)
&lt;/pre&gt;

&lt;p&gt;says &quot;synchronize this future with f2 until at least time t1&quot;.  If (now f2) is less than t1, then this will retry and the transaction should get re-run when either (a) (now f2) &gt;= t1, or (b) the results of maybeSTM (value f2) changes, that is, f2 resolved to a particular value.&lt;/p&gt;

&lt;p&gt;(3) I&#039;m sure I haven&#039;t done this properly yet, but it should be pretty easy to solve with a TVar that holds the value of the future once it gets determined; the caching problem seems to apply more to Events (streams of futures) than futures themselves; a future will only ever return its single correct value or retry.  I suppose that in the &lt;*&gt; case that the first future could resolve, and then we will go through and re-calculate it when the second future resolves.  I&#039;ll think about that and see if I can come up with a good solution.&lt;/p&gt;

&lt;p&gt;Overall, STM doesn&#039;t seem -quite- as good a fit as I originally thought; the idea of a value that becomes known through computation and then stays that way is exactly what a pure value does via laziness.  I need to think about this problem some more, but it&#039;s been a lot of fun!&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Conal, hopefully I can answer your questions satisfactorily.</p>

<p>(1) Absolutely: that was the goal.  In particular, here is the implementation of &#8220;force&#8221;:</p>

<pre>
type FTime t = AddBounds t
type F t a = (FTime t, a)
force :: Future t a -&gt; F t a
force f = unsafePerformIO $ allowNestedTransactions $
             atomically $ value f
</pre>

<p>allowNestedTransactions is a hack I came up with to do, well, what its name says:</p>

<pre>
allowNestedTransactions m = do
    v &lt;- newEmptyMVar
    forkIO (m &gt;&gt;= putMVar v)
    takeMVar v
</pre>

<p>This uses a separate thread to trick the STM runtime into allowing a nested transaction, but the behavior is exactly that of a single-threaded program; the MVar handles control flow and makes sure that the originating thread blocks until the computation on the forked thread completes.  Ideally this won&#8217;t be necessary in a future implementation of STM.  Of course this is only required if &#8220;force x&#8221; is used as a pure value inside another STM computation, and none of the reactive code calls force except for &#8220;occs&#8221;.  But pure values should act like pure values, so something was required.</p>

<p>(2) Exactly; here are the requirements for a correct future:
If f denotes (t0, a), then:</p>

<pre>
waitFor f t ~&gt; return ()
  =&gt; forall (s &lt;= t). waitFor f s ~&gt; return ()
-- That is, if waitFor f t doesn't retry, then waitFor f t
--   doesn't retry for earlier t either.

waitFor f t &gt;&gt; maybeSTM (value f) ~&gt; return Nothing
   =&gt; t0 &gt; t
-- That is, if waitFor f t doesn't retry, and value f
--  does, then f is not yet available at time t.
</pre>

<p>Another way to look at it is to treat each future as having a universe which has its own current time.  Then we have the following rules:</p>

<pre>
now :: Future a -&gt; STM Time -- never retries

waitFor f t = do
    n &lt;- now f
    if (t &lt;= n) then return () else retry
-- In fact, I define "now" for a future as "the largest t
--   such that waitFor f t does not retry"

value f = do
    n &lt;- now f
    if (n &gt;= t0) -- this is the t0 from the denotation of the future
      then return (t0, a)
      else retry

now (pure x) = return maxBound
now (firstFuture f1 f2) = min &lt;$&gt; now f1 &lt;*&gt; now f2
</pre>

<p>So, in &#8220;firstFuture&#8221;, this code snippet:</p>

<pre>
        (Just (t1, v1), Nothing) -&gt; do
            waitFor f2 t1
            return (t1, v1)
</pre>

<p>says &#8220;synchronize this future with f2 until at least time t1&#8243;.  If (now f2) is less than t1, then this will retry and the transaction should get re-run when either (a) (now f2) &gt;= t1, or (b) the results of maybeSTM (value f2) changes, that is, f2 resolved to a particular value.</p>

<p>(3) I&#8217;m sure I haven&#8217;t done this properly yet, but it should be pretty easy to solve with a TVar that holds the value of the future once it gets determined; the caching problem seems to apply more to Events (streams of futures) than futures themselves; a future will only ever return its single correct value or retry.  I suppose that in the &lt;*&gt; case that the first future could resolve, and then we will go through and re-calculate it when the second future resolves.  I&#8217;ll think about that and see if I can come up with a good solution.</p>

<p>Overall, STM doesn&#8217;t seem -quite- as good a fit as I originally thought; the idea of a value that becomes known through computation and then stays that way is exactly what a pure value does via laziness.  I need to think about this problem some more, but it&#8217;s been a lot of fun!</p>]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/simply-efficient-functional-reactivity/comment-page-1/#comment-3875</link>
		<dc:creator>conal</dc:creator>
		<pubDate>Tue, 22 Apr 2008 22:13:34 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/posts/simply-efficient-functional-reactivity/#comment-3875</guid>
		<description>&lt;p&gt;Ryan: I read your post and have some questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does your &lt;code&gt;Future a&lt;/code&gt; type have the same denotation as in my paper, namely &lt;code&gt;(Time,a)&lt;/code&gt;?  Does &lt;code&gt;firstFuture&lt;/code&gt; have the same semantics as my &lt;code&gt;mappend&lt;/code&gt; (picking the earlier future)?&lt;/li&gt;
&lt;li&gt;What use do you make of &lt;code&gt;waitFor&lt;/code&gt;?  Related: what&#039;s the semantics of &lt;code&gt;firstFuture&lt;/code&gt;, and what do its calls to &lt;code&gt;waitFor&lt;/code&gt; accomplish?  I see the comment &quot;start over if something changes in the meantime&quot;, but I don&#039;t see how the waiting influences the returned value, so I don&#039;t know how you could get determinate semantics.  Does &lt;code&gt;waitFor&lt;/code&gt; sometimes &lt;code&gt;retry&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What&#039;s your implementation of &lt;code&gt;fmap&lt;/code&gt; and &lt;code&gt;(&lt;*&gt;)&lt;/code&gt; on your &lt;code&gt;Future&lt;/code&gt; representation, and have you checked whether it re-applies functions each time the result is accessed?  My first implementation used STM in a similar way, and I realized that the obvious (to me) &lt;code&gt;fmap&lt;/code&gt; and &lt;code&gt;(&lt;*&gt;)&lt;/code&gt; implementations failed to cache their values.  My fix (and Jake McArthur&#039;s--see comments on your post), used a writer thread.&lt;/li&gt;
&lt;/ul&gt;
</description>
		<content:encoded><![CDATA[<p>Ryan: I read your post and have some questions:</p>

<ul>
<li>Does your <code>Future a</code> type have the same denotation as in my paper, namely <code>(Time,a)</code>?  Does <code>firstFuture</code> have the same semantics as my <code>mappend</code> (picking the earlier future)?</li>
<li>What use do you make of <code>waitFor</code>?  Related: what&#8217;s the semantics of <code>firstFuture</code>, and what do its calls to <code>waitFor</code> accomplish?  I see the comment &#8220;start over if something changes in the meantime&#8221;, but I don&#8217;t see how the waiting influences the returned value, so I don&#8217;t know how you could get determinate semantics.  Does <code>waitFor</code> sometimes <code>retry</code>?</li>
<li>What&#8217;s your implementation of <code>fmap</code> and <code>(&lt;*&gt;)</code> on your <code>Future</code> representation, and have you checked whether it re-applies functions each time the result is accessed?  My first implementation used STM in a similar way, and I realized that the obvious (to me) <code>fmap</code> and <code>(&lt;*&gt;)</code> implementations failed to cache their values.  My fix (and Jake McArthur&#8217;s&#8211;see comments on your post), used a writer thread.</li>
</ul>]]></content:encoded>
	</item>
</channel>
</rss>
