<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; interaction</title>
	<atom:link href="http://conal.net/blog/tag/interaction/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>Functional interactive behavior</title>
		<link>http://conal.net/blog/posts/functional-interactive-behavior</link>
		<comments>http://conal.net/blog/posts/functional-interactive-behavior#comments</comments>
		<pubDate>Wed, 10 Dec 2008 09:26:50 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[interaction]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=70</guid>
		<description><![CDATA[In a previous post, I presented a fundamental reason why classic FRP does not fit interactive behavior, which is that the semantic model captures only the influence of time and not other input. I also gave a simple alternative, with a simple and general model for temporal and spatial transformation, in which input behavior is [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Functional interactive behavior

Tags: FRP, functional reactive programming, interaction

URL: http://conal.net/blog/posts/functional-interactive-behavior/

-->

<!-- references -->

<!-- teaser -->

<p>In a previous post, I presented a fundamental reason <em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">why classic FRP does not fit interactive behavior</a></em>, which is that the semantic model captures only the influence of time and not other input.
I also gave a simple alternative, with a simple and general model for temporal and spatial transformation, in which input behavior is transformed inversely to the transformation of output behavior.</p>

<p>The semantic model I suggested is the same as used in &#8220;Arrow FRP&#8221;, from <a href="http://conal.net/papers/genuinely-functional-guis.pdf" title="Paper: &quot;Genuinely Functional User Interfaces&quot;">Fruit</a> and <a href="http://haskell.org/haskellwiki/Yampa" title="Wiki page">Yampa</a>.
I want, however, a more convenient and efficient way to package up that model, which is the subject of the post you are reading now.</p>

<p>Next, we took a close look at one awkward aspect of classic FRP for interactive behavior, namely the need to <a href="http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/" title="blog post">trim inputs</a>, and how trimming relates to <a href="http://conal.net/blog/tag/comonad/">comonadic</a> FRP.
The <code>trim</code> function allows us to define multi-phase interactive behaviors correctly and efficiently, but its use is tedious and is easy to get wrong.
It thus fails to achieve what I want from functional programming in general and FRP in particular, which is to enable writing simple, natural descriptions, free of mechanical details.</p>

<p>The current post hides and automates the mechanics of trimming, so that the intent of an interactive behavior can be expressed directly and executed correctly and efficiently.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-70"></span></p>

<p>As before, I&#8217;ll adopt two abbreviations, for succinctness:</p>

<pre><code>type B = Behavior
type E = Event
</code></pre>

<h3>Safe and easy trimming</h3>

<p><a href="http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/" title="blog post">Previously</a>, I defined an interactive cat behavior as follows:</p>

<pre><code>cat3 :: B World -&gt; B Cat
cat3 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trimf wake   world) `mappend`
                (uncurry eat   &lt;$&gt; trimf hunger world))
</code></pre>

<p>I&#8217;d really like to write the following</p>

<pre><code>-- ideal:
cat4 = sleep `switcher` ((prowl &lt;$&gt; wake) `mappend` (eat &lt;$&gt; hunger)) 
</code></pre>

<p>Let&#8217;s see how close we can get.</p>

<p>I can see right off I&#8217;ll have to replace or generalize <code>switcher</code>.
For now, I&#8217;ll replace it:</p>

<pre><code>switcherf :: (B i -&gt; B o)
          -&gt; (B i -&gt; E (B i -&gt; B o))
          -&gt; (B i -&gt; B o)
</code></pre>

<p>This function will have to manage trimming:</p>

<pre><code>bf `switcherf` ef =  i -&gt;
  bf i `switcher` (uncurry ($) &lt;$&gt; trimf ef i)
</code></pre>

<p>I won&#8217;t have to replace <code>mappend</code>, since it&#8217;s a method and so can have a variety of types.
In this case, <code>mappend</code> applies to a function from behaviors to events.
Fortunately, the function monoid is exactly what we need:</p>

<pre><code>instance Monoid b =&gt; Monoid (a -&gt; b) where
  mempty        = const mempty
  f `mappend` g =  a -&gt; f a `mappend` f b
</code></pre>

<p>or the more lovely standard form for applicative functors:</p>

<pre><code>instance Monoid b =&gt; Monoid (a -&gt; b) where
  mempty  = pure   mempty
  mappend = liftA2 mappend
</code></pre>

<p>The use of <code>(&lt;$&gt;)</code> (i.e., <code>fmap</code>) in <code>cat4</code> above won&#8217;t work.
We want instead to <code>fmap</code> inside the <em>result</em> of a function from behaviors to events.
Using the style of <a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">semantic editor combinators</a>, we get the following definition, which is fairly close to our ideal:</p>

<pre><code>cat4 = sleep `switcherf`
         ((result.fmap) prowl wake `mappend` (result.fmap) eat hunger)
</code></pre>

<h3>Generalized switching</h3>

<p>To generalize <code>switcher</code>, introduce a new type class:</p>

<pre><code>class Switchable b e where switcher :: b -&gt; e b -&gt; b
</code></pre>

<p>The original Reactive <code>switcher</code> is a special case:</p>

<pre><code>instance Switchable (B a) E where switcher = R.switcher
</code></pre>

<p>We can switch among tuples and among other containers of switchables.
For instance,</p>

<pre><code>instance (Functor e, Switchable b e, Switchable b' e)
      =&gt; Switchable (b,b') e where
  (b,b') `switcher` e = ( b  `switcher` (fst &lt;$&gt; e)
                        , b' `switcher` (snd &lt;$&gt; e) )
</code></pre>

<h3>Temporal values</h3>

<p>Looking through the examples above, all we really had to do with the input behavior was to compute all remainders.
I used</p>

<pre><code>duplicate :: B a -&gt; B (B a)
</code></pre>

<p>More generally,</p>

<pre><code>class Temporal a where remainders :: a -&gt; B a
</code></pre>

<p>Behaviors and events are included as a special case,</p>

<pre><code>instance Temporal (B a) where remainders = duplicate

instance Temporal (E a) where remainders = ...
</code></pre>

<p>Temporal values combine without losing their individuality, which allows efficient change-driven evaluation as in <em><a href="http://conal.net/blog/posts/simply-efficient-functional-reactivity/" title="blog post">Simply efficient functional reactivity</a></em>:</p>

<pre><code>instance (Temporal a, Temporal b) =&gt; Temporal (a,b) where
  remainders (a,b) = remainders a `zip` remainders b
</code></pre>

<p>Similarly for other triples and other data structures.</p>

<p>Sometimes it&#8217;s handy to carry static information along with dynamic information.
Static types can be made trivially temporal:</p>

<pre><code>instance Temporal Bool where remainders = pure
instance Temporal Int  where remainders = pure
-- etc
</code></pre>

<p>With this <code>Temporal</code> class, the trimming definitions above have more general types.</p>

<pre><code>trim  :: Temporal i =&gt; E o -&gt; i -&gt; E (o, i)

trimf :: Temporal i =&gt; (i -&gt; E o) -&gt; (i -&gt; E (o, i))
</code></pre>

<p>As does function switching:</p>

<pre><code>switcherf :: (Temporal i, Switchable o E) =&gt;
             (i -&gt; o) -&gt; (i -&gt; E (i -&gt; o)) -&gt; i -&gt; o
</code></pre>

<h3>Types for functional interactive behavior</h3>

<p>We&#8217;ve gotten almost to my ideal cat definition.
We cannot, however, use <code>switcher</code> or <code>(&lt;$&gt;)</code> here with functions from behaviors to behaviors, because the types don&#8217;t fit.</p>

<p>To cross the last gap, let&#8217;s define new types corresponding to the idioms we&#8217;ve seen repeatedly above.</p>

<pre><code>-- First try
type i :~&gt; o = BI (B i -&gt; B o)
type i :-&gt; o = EI (B i -&gt; E o)
</code></pre>

<p>Or, using <a href="http://haskell.org/haskellwiki/TypeCompose" title="Wiki page">type composition</a>:</p>

<pre><code>-- Second try
type (:~&gt;) i = (-&gt;) (B i) :. B
type (:-&gt;) i = (-&gt;) (B i) :. E
</code></pre>

<p>The advantage of type composition is that we get some useful definitions for free, including <code>Functor</code> and <code>Applicative</code> instances.</p>

<p>However, there&#8217;s a problem with both versions.
They limit us to a single behavior as input.
A realistic interactive environment has many inputs, including a mixture of behaviors and events.</p>

<p>In Yampa, that mixture is combined into a single behavior, leading to two difficulties:</p>

<ul>
<li>The distinction between behaviors and events gets lost, as well as (I think) accurate and minimal-latency event detection and response.</li>
<li>The bundled input environment changes whenever any component changes, leading to everything getting recomputed and redisplayed when anything changes.</li>
</ul>

<p>To avoid these problems, I&#8217;ll take a different approach.
Generalize inputs from behaviors to arbitrary <code>Temporal</code> values, which include behaviors, events and tuples and structures of temporal values.</p>

<p>The types for interactive behaviors and interactive events are</p>

<pre><code>type (:~&gt;) i = (-&gt;) i :. B
type (:-&gt;) i = (-&gt;) i :. E
</code></pre>

<p>So <code>i :~&gt; o</code> is like <code>i -&gt; B o</code>, and <code>i :-&gt; o</code> is like <code>i -&gt; E o</code>.</p>

<p>Switching for interactive behaviors wraps the <code>switcherf</code> function from above:</p>

<pre><code>instance Temporal i =&gt; Switchable (i :~&gt; o) ((:-&gt;) i) where
  switcher = inO2 $  bf ef -&gt; bf `switcherf` (result.fmap) unO ef
</code></pre>

<p>The <code>inO2</code> and <code>unO</code> functions from <a href="http://haskell.org/haskellwiki/TypeCompose" title="Wiki page">TypeCompose</a> just manipulate <code>newtype</code> wrappers.
See <em><a href="http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/" title="blog post">Prettier functions for wrapping and wrapping</a></em>.</p>

<p>This definition is actually more general than the type given here.
For instance, it can be used to switch between interactive <em>events</em> as well as interactive <em>behaviors</em>.
To see the generalization, first abstract out the commonality between <code>(:~&gt;)</code> and <code>(:-&gt;)</code>:</p>

<pre><code>type i :-&gt;. f = (-&gt;) i :. f

type (:~&gt;) i = i :-&gt;. B
type (:-&gt;) i = i :-&gt;. E
</code></pre>

<p>The same instance code but with a more general type:</p>

<pre><code>instance (Temporal i, Switchable (f o) E)
      =&gt; Switchable ((i :-&gt;. f) o) ((:-&gt;) i) where
  switcher = inO2 $  bf ef -&gt; bf `switcherf` (result.fmap) unO ef
</code></pre>

<p>We can also switch between interactive <em>collections</em> of behaviors and events, though not with the <code>(:-&gt;.)</code> wrapping.</p>

<h3>Where are we?</h3>

<p>Almost all of the pieces are in place now.
Another post will relate input trimming to the time transformation of interactive behaviors, as discussed in 
<em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">Why classic FRP does not fit interactive behavior</a></em>.
Also, how interactive FRP relates to <em><a href="http://conal.net/blog/posts/sequences-segments-and-signals/" title="blog post">Sequences, segments, and signals</a></em>.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=70&amp;md5=adc2fb47d1bda8d4267464ef19f66859"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/functional-interactive-behavior/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffunctional-interactive-behavior&amp;language=en_GB&amp;category=text&amp;title=Functional+interactive+behavior&amp;description=In+a+previous+post%2C+I+presented+a+fundamental+reason+why+classic+FRP+does+not+fit+interactive+behavior%2C+which+is+that+the+semantic+model+captures+only+the+influence+of+time+and...&amp;tags=comonad%2CFRP%2Cfunctional+reactive+programming%2Cinteraction%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Trimming inputs in functional reactive programming</title>
		<link>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming</link>
		<comments>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming#comments</comments>
		<pubDate>Wed, 10 Dec 2008 09:00:33 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[comonad]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[interaction]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=71</guid>
		<description><![CDATA[This post takes a close look at one awkward aspect of classic (non-arrow) FRP for interactive behavior, namely the need to trim (or &#8220;age&#8221;) old input. Failing to trim results in behavior that is incorrect and grossly inefficient. Behavior trimming connects directly into the comonad interface mentioned in a few recent posts, and is what [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Trimming inputs in functional reactive programming

Tags: FRP, functional reactive programming, interaction, comonad

URL: http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/

-->

<!-- references -->

<!-- teaser -->

<p>This post takes a close look at one awkward aspect of <em>classic</em> (non-arrow) FRP for interactive behavior, namely the need to <em>trim</em> (or &#8220;age&#8221;) old input.
Failing to trim results in behavior that is incorrect and grossly inefficient.</p>

<p>Behavior trimming connects directly into the <a href="http://conal.net/blog/tag/comonad/">comonad</a> interface mentioned in a few recent posts, and is what got me interested in comonads recently.</p>

<p>In absolute-time FRP, trimming has a purely operational significance.
Switching to relative time, trimming is recast as a semantically familiar operation, namely the generalized <code>drop</code> function used in two <a href="http://conal.net/blog/tag/segment/">recent posts</a>.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-71"></span></p>

<p>In the rest of this post, I&#8217;ll adopt two abbreviations, for succinctness:</p>

<pre><code>type B = Behavior
type E = Event
</code></pre>

<h3>Trimming inputs</h3>

<p>An awkward aspect of classic FRP has to do with switching phases of behavior.
Each phase is a function of some static (momentary) input and some dynamic (time-varying) input, e.g.,</p>

<pre><code>sleep :: B World -&gt; B Cat
eat   :: Appetite   -&gt; B World -&gt; B Cat
prowl :: Friskiness -&gt; B World -&gt; B Cat

wake   :: B World -&gt; E Friskiness
hunger :: B World -&gt; E Appetite
</code></pre>

<p>As a first try, our cat prowls upon waking and eats when hungry, taking into account its surrounding world:</p>

<pre><code>cat1 :: B World -&gt; B Cat
cat1 world = sleep world `switcher`
               ((flip prowl world &lt;$&gt; wake   world) `mappend`
                (flip eat   world &lt;$&gt; hunger world))
</code></pre>

<p>The <code>(&lt;$&gt;)</code> here, from <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html" title="Haskell module documentation">Control.Applicative</a>, is a synonym for <code>fmap</code>.
In this context,</p>

<pre><code>(&lt;$&gt;) :: (a -&gt; B Cat) -&gt; E a -&gt; E (B Cat)
</code></pre>

<p>The FRP <code>switcher</code> function switches to new behavior phases as they&#8217;re generated by an event, beginning with a given initial behavior:</p>

<pre><code>switcher :: B a -&gt; E (B a) -&gt; B a
</code></pre>

<p>And the <code>mappend</code> here merges two events into one, combining their occurrences.</p>

<p>When switching phases, we generally want the new phase to start responding to input exactly where the old phase left off.
If we&#8217;re not careful, however, the new phase will begin with an old input.
I&#8217;ve made exactly this mistake in defining <code>cat1</code> above.
Consequently, each new phase will begin by responding to all of the old input and then carry on.
This meaning is both unintended and is very expensive (the dreaded &#8220;space-time&#8221; leak).</p>

<p>This difficulty is not unique to FRP.
In functional programming, we have to be careful how we hold onto our inputs, so that they can get accessed and freed incrementally.
I don&#8217;t think the difficulty arises much in imperative programming, because input (like output) is destructively altered, and programs have access only to the current state.</p>

<p>I&#8217;ve done it wrong above, in defining <code>cat</code>.
How can I do it right?
The solution/hack I came up for Fran was to add a function that trims (&#8220;ages&#8221;) dynamic input while waiting for event occurrences.</p>

<pre><code>trim :: B b -&gt; E a -&gt; E (a, B b)
</code></pre>

<p><code>trim b e</code> follows <code>b</code> and <code>e</code> in parallel.
At each occurrence of <code>e</code>, the remainder of <code>b</code> is paired up with the event data from <code>e</code>.</p>

<p>Now I can define the interactive, multi-phase behavior I intend:</p>

<pre><code>cat2 :: B World -&gt; B Cat
cat2 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trim world (wake   world)) `mappend`
                (uncurry eat   &lt;$&gt; trim world (hunger world)))
</code></pre>

<p>The event <code>trim world (wake world)</code> occurs whenever <code>wake world</code> does, and has as event data the cat&#8217;s friskiness on waking, plus the remainder of the cat&#8217;s world at the occurrence time.
The &#8220;<code>uncurry prowl &lt;$&gt;</code>&#8221; applies <code>prowl</code> to each friskiness and remainder world on waking.
Similarly for the other phase.</p>

<p>I think this version defines the behavior I want and that it can run efficiently, assuming that <code>trim e b</code> traverses <code>e</code> and <code>b</code> in parallel (so that laziness doesn&#8217;t cause a space-time leak).
However, this definition is much trickier than what I&#8217;m looking for.</p>

<p>One small improvement is to abstract a trimming pattern:</p>

<pre><code>trimf :: (B i -&gt; E o) -&gt; (B i -&gt; E (o, B i))
trimf ef i = trim i (ef i)

cat3 :: B World -&gt; B Cat
cat3 world = sleep world `switcher`
               ((uncurry prowl &lt;$&gt; trimf wake   world) `mappend`
                (uncurry eat   &lt;$&gt; trimf hunger world))
</code></pre>

<h3>A comonad comes out of hiding</h3>

<p>The <code>trim</code> functions above look a lot like snapshotting of behaviors:</p>

<pre><code>snapshot  :: B b -&gt; E a -&gt; E (a,b)

snapshot_ :: B b -&gt; E a -&gt; E b
</code></pre>

<p>Indeed, the meanings of trimming and snapshotting are very alike.
They both involving following an event and a behavior in parallel.
At each event occurrence, <code>snapshot</code> takes the <em>value</em> of the behavior at the occurrence time, while <code>trim</code> takes the entire remainder from that time on.</p>

<p>Given this similarlity, can one be defined in terms of the other?
If we had a function to &#8220;extract&#8221; the first defined value of a behavior, we could define<code>snapshot</code> via <code>trim</code>.</p>

<pre><code>b `snapshot` e = fmap (second extract) (b `trim` e)

extract :: B a -&gt; a
</code></pre>

<p>We can also define <code>trim</code> via <code>snapshot</code>, if we have a way to get all trimmed versions of a behavior &#8212; to &#8220;duplicate&#8221; a one-level behavior into a two-level behavior:</p>

<pre><code>b `trim` e = duplicate b `snapshot` e

duplicate :: B a -&gt; B (B a)
</code></pre>

<p>If you&#8217;ve run into comonads, you may recognize <code>extract</code> and <code>duplicate</code> as the operations of <code>Comonad</code>, dual to <code>Monad</code>&#8216;s <code>return</code> and <code>join</code>.
It was this definition of <code>trim</code> that got me interested in comonads recently.</p>

<p>In the style of <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em>,</p>

<pre><code>snapshot = (result.result.fmap.second) extract trim
</code></pre>

<p>or</p>

<pre><code>trim = argument remainders R.snapshot
</code></pre>

<p>The <code>extract</code> function is problematic for classic FRP, which uses absolute (global) time.
We don&#8217;t know with which time to sample the behavior.
With <em>relative-time FRP</em>, we&#8217;ll only ever sample at (local) time 0.</p>

<h3>Relative time</h3>

<p>So far, the necessary trimming has strong operational significance: it prevents obsolete reactions and the consequent space-time leaks.</p>

<p>If we switch from absolute time to relative time, then trimming becomes something with familiar semantics, namely <code>drop</code>, as generalized and used in two of my previous posts, <em><a href="http://conal.net/blog/posts/sequences-functions-and-segments/" title="blog post">Sequences, streams, and segments</a></em> and <em><a href="http://conal.net/blog/posts/sequences-segments-and-signals/" title="blog post">Sequences, segments, and signals</a></em>.</p>

<p>The semantic difference: trimming (absolute time) erases early content in an input; while dropping (relative time) shifts input backward in time, losing the early content in the same way as <code>drop</code> on sequences.</p>

<h3>What&#8217;s next?</h3>

<p>While input trimming can be managed systematically, doing so explicitly is tedious and error prone.
A follow-up post will automatically apply the techniques from this post.
Hiding and automating the mechanics of trimming allows interactive behavior to be expressed correctly and without distraction.</p>

<p>Another post will relate input trimming to the time transformation of interactive behaviors, as discussed in 
<em><a href="http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/" title="blog post">Why classic FRP does not fit interactive behavior</a></em>.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=71&amp;md5=842949917d89f4d726e5c20b26d662bc"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/trimming-inputs-in-functional-reactive-programming/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ftrimming-inputs-in-functional-reactive-programming&amp;language=en_GB&amp;category=text&amp;title=Trimming+inputs+in+functional+reactive+programming&amp;description=This+post+takes+a+close+look+at+one+awkward+aspect+of+classic+%28non-arrow%29+FRP+for+interactive+behavior%2C+namely+the+need+to+trim+%28or+%26%238220%3Bage%26%238221%3B%29+old+input.+Failing+to+trim+results...&amp;tags=comonad%2CFRP%2Cfunctional+reactive+programming%2Cinteraction%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Why classic FRP does not fit interactive behavior</title>
		<link>http://conal.net/blog/posts/why-classic-frp-does-not-fit-interactive-behavior</link>
		<comments>http://conal.net/blog/posts/why-classic-frp-does-not-fit-interactive-behavior#comments</comments>
		<pubDate>Wed, 10 Dec 2008 06:45:48 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[FRP]]></category>
		<category><![CDATA[functional reactive programming]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[perspective]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=69</guid>
		<description><![CDATA[In functional reactive programming (FRP), the type we call &#8220;behaviors&#8221; model non-interactive behavior. To see why, just look at the semantic model: t -&#62; a, for some notion t of time. One can argue as follows that this model applies to interactive behavior as well. Behaviors interacting with inputs are functions of time and of [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Why classic FRP does not fit interactive behavior

Tags: FRP, functional reactive programming, interaction, perspective

URL: http://conal.net/blog/posts/why-classic-FRP-does-not-fit-interactive-behavior/

-->

<!-- references -->

<!-- teaser -->

<p>In functional reactive programming (FRP), the type we call &#8220;behaviors&#8221; model <em>non-interactive</em> behavior.
To see why, just look at the semantic model: <code>t -&gt; a</code>, for some notion <code>t</code> of time.</p>

<p>One can argue as follows that this model applies to interactive behavior as well.
Behaviors interacting with inputs are functions of time and of inputs.
Those inputs are also functions of time, so behaviors are just functions of time.
I held this perspective at first, but came to see a lack of composability.</p>

<p>My original FRP formulations (<a href="http://conal.net/Fran" title="Functional reactive animation">Fran</a> and its predecessors <a href="http://conal.net/tbag/" title="Project web page">TBAG</a> and <a href="http://conal.net/papers/ActiveVRML/" title="Tech report: &quot;A Brief Introduction to ActiveVRML&quot;">ActiveVRML</a>), as well as the much more recent library <a href="http://haskell.org/haskellwiki/Reactive" title="Wiki page">Reactive</a>, can be and are used to describe interactive behavior.
For simple sorts of things, this use works out okay.
When applications get a bit richer, the interface and semantics strain.
If you&#8217;ve delved a bit, you&#8217;ll have run into the signs of strain, with coping mechanisms like <em>start times</em>, <em>user arguments</em> and <em>explicit aging</em> of inputs, as you avoid the dreaded <em>space-time leaks</em>.</p>

<!--
**Edits**:

* 2008-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-69"></span></p>

<h3>Behaviors</h3>

<p>Suppose I define an object that pays attention to an input that&#8217;s interesting near a certain time.
For instance, a cat chasing a bird in the back yard one morning last week.
Now shift the behavior a week forward to this morning.
The result is just a week-delayed form of the earlier behavior, displaying reactions to week-old input.
The original interactive behavior (the cat) was fed input (bird and yard) from a week ago, the result was recorded, and that recording is replayed a week later.</p>

<p>Written functionally,</p>

<pre><code>laterObserveCat :: Behavior World -&gt; Behavior Cat
laterObserveCat = later week . cat
</code></pre>

<p>where</p>

<pre><code>world :: Behavior World
cat   :: Behavior World -&gt; Behavior Cat

later :: Duration -&gt; Behavior a -&gt; Behavior a
</code></pre>

<p>We can also sit in the living room, five meters north of the back yard, and watch the cat via a camera.</p>

<pre><code>livingRoomObserveCat :: Behavior World -&gt; Behavior Cat
livingRoomObserveCat = north (5 * meter) . cat
</code></pre>

<p>Typically recordings are moved <em>both</em> in space and in time.
For example, record the cat in the back yard one week and watch the recording in the living room a week later:</p>

<pre><code>replayLRL :: Behavior World -&gt; Behavior Cat
replayLRL = later week . north (5 * meter) . cat
</code></pre>

<h3>Interactive behavior</h3>

<p>I&#8217;ve just described transforming a <em>non-interactive</em> behavior (recording) in time and space.
That non-interactive behavior resulted applying an interactive behavior (the cat) to some input (bird and yard).
An <em>interactive</em> behavior is simply a function from non-interactive behavior (time-varying input) to non-interactive behavior (time-varying output).</p>

<p>Consider what it means to transform an <em>interactive</em> behavior in space.
I pick up the cat and carry her five meters north, into the living room.
The cat has a different perspective, which is that her environment moves five meters south.
For instance, the mouse that was one meter south of her is now six meters sounth.</p>

<p>If I lift the cat four feet above the ground, she sees the ground now four <em>below</em> her.
If I spin her clockwise, her environment spins counter-clockwise.
If I point my shrinking ray at her, she sees her world as growing larger, and she flees from the giant mice.</p>

<p>We can play the perspective game in time as well as space.
I point my speed-up ray at the cat, and she perceives her environment slow down.</p>

<p>When I say I move the cat north and she see her environment move south, I am not suggesting that there are two alternative perspectives and we might take either one.
Rather, a complete picture combines both movements.
The behavior my cat exhibits when I pick her up is composed of three transformations:</p>

<ul>
<li>The world moves south;</li>
<li>The cat perceives this more southerly world and responds to it; and</li>
<li>The resulting cat behavior is moved north.</li>
</ul>

<p>Written functionally,</p>

<pre><code>livingRoomCat :: Behavior World -&gt; Behavior Cat
livingRoomCat = north (5 * meter) . cat . south (5 * meter)
</code></pre>

<p>Similarly with other spatial transformation, each with paired inverse transformations.
And similarly in time, e.g.,</p>

<pre><code>laterCat :: Behavior World -&gt; Behavior Cat
laterCat = later week . cat . earlier week
</code></pre>

<p>So there&#8217;s a semantically consistent model of transforming interactive behaviors in time or space, and this model explains the difference between transformation of non-interactive behavior and of interactive behavior.</p>

<h3>Aside</h3>

<p>Comparing these two definitions with the previous two suggests an alternative implementation.
Refactoring,</p>

<pre><code>laterCat :: Behavior World -&gt; Behavior Cat
laterCat = laterObserveCat . earlier week
</code></pre>

<p>Instead of carrying the interactive cat a week ahead in time, this definition suggests that we move the world (other than the cat) <em>back</em> one week, record the cat interacting with it, and hold onto that recording to watch a week later.
My back-of-the-envelope calculations suggest that this second implementation is less resource-efficient than the first one, so I&#8217;ll not consider it further in this post.</p>

<h3>Arrow FRP</h3>

<p>When we use for an interactive setting the tools suited to non-interactive behaviors, we&#8217;re begging for space leaks (filling up recording media) and time leaks (fast-forwarding through old recorded matter to catch up with what we want to see).
These problems are what people experience when programming explicitly with  might call &#8220;classic FRP&#8221;, i.e., programming explicitly with (non-interactive) behaviors.
Out of this experience was born &#8220;Arrow FRP&#8221;, as in <a href="http://conal.net/papers/genuinely-functional-guis.pdf" title="Paper: &quot;Genuinely Functional User Interfaces&quot;">Fruit</a> and <a href="http://haskell.org/haskellwiki/Yampa" title="Wiki page">Yampa</a>.
The idea of Arrow FRP was to program with a type of &#8220;signal functions&#8221;, which can be thought of as mappings between behaviors:</p>

<pre><code>type SF a b = Behavior a -&gt; Behavior b
</code></pre>

<p>(Behaviors were also renamed to &#8220;signals&#8221;, but I&#8217;ll stick with &#8220;behaviors&#8221; for now.)
We can just look at semantic model for signal transformers and see that they&#8217;re about <em>interactive</em> behavior.</p>

<p>A lot of work was done with this new model, mostly growing out of Paul Hudak&#8217;s group at Yale.
It addressed the inherent awkwardness of the explicit-behavior style.</p>

<p>Despite this fundamental advantage of signal transformers, why am I still fooling around with the &#8220;classic&#8221; (pre-arrow) style?</p>

<ul>
<li>The <code>Arrow</code> 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 <em><a href="http://conal.net/blog/posts/simply-efficient-functional-reactivity/" title="Blog post">Simply efficient functional reactivity</a></em>.</li>
<li>There was no room for the distinction between behaviors and events.  I&#8217;d love to see how to combine them without losing expressiveness or semantic accuracy, and I haven&#8217;t yet.</li>
<li>Arrow programming is very awkward without the special arrow notation and has more of a sequential style than I like with the arrow notation.  I missed the functional feel of classic FRP.</li>
</ul>

<h3>Coming up</h3>

<p>Given the fundamental semantic fit between signal transformers for the problem domain of interactive behavior, I&#8217;d like to come up wh convenient and efficient packaging.
The next posts will describe the packaging I&#8217;m trying out now.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=69&amp;md5=1c05654dd716cacaea14eb65a6d8945b"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/why-classic-frp-does-not-fit-interactive-behavior/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fwhy-classic-frp-does-not-fit-interactive-behavior&amp;language=en_GB&amp;category=text&amp;title=Why+classic+FRP+does+not+fit+interactive+behavior&amp;description=In+functional+reactive+programming+%28FRP%29%2C+the+type+we+call+%26%238220%3Bbehaviors%26%238221%3B+model+non-interactive+behavior.+To+see+why%2C+just+look+at+the+semantic+model%3A+t+-%26gt%3B+a%2C+for+some+notion+t+of...&amp;tags=FRP%2Cfunctional+reactive+programming%2Cinteraction%2Cperspective%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
