<?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>weaselhat &#187; Flapjax</title>
	<atom:link href="http://www.weaselhat.com/category/software/flapjax/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.weaselhat.com</link>
	<description></description>
	<lastBuildDate>Sat, 29 May 2010 09:17:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Flapjax: A Programming Language for Ajax Applications</title>
		<link>http://www.weaselhat.com/2009/08/13/flapjax-2/</link>
		<comments>http://www.weaselhat.com/2009/08/13/flapjax-2/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 16:00:29 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[Papers]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/?p=122</guid>
		<description><![CDATA[I am immensely pleased to report that our paper on Flapjax was accepted to OOPSLA 2009. This paper presents Flapjax, a language designed for contemporary Web applications. These applications communicate with servers and have rich, interactive interfaces. Flapjax provides two key features that simplify writing these applications. First, it provides event streams, a uniform abstraction [...]]]></description>
			<content:encoded><![CDATA[<p>I am immensely pleased to report that <a href="http://www.cis.upenn.edu/~mgree/papers/oopsla2009_flapjax.pdf">our paper on Flapjax</a> was accepted to <a href="http://www.oopsla.org/oopsla2009/" title="My favorite conference name to say, perhaps my least favorite to type.  OOPSPLA, every time.">OOPSLA 2009</a>.</p>
<blockquote><p>
This paper presents Flapjax, a language designed for contemporary Web applications. These applications communicate with servers and have rich, interactive interfaces. Flapjax provides two key features that simplify writing these applications. First, it provides event streams, a uniform abstraction for communication within a program as well as with external Web services. Second, the language itself is reactive: it automatically tracks data dependencies and propagates updates along those data?ows. This allows developers to write reactive interfaces in a declarative and compositional style.</p>
<p>Flapjax is built on top of JavaScript. It runs on unmodi?ed browsers and readily interoperates with existing JavaScript code. It is usable as either a programming language (that is compiled to JavaScript) or as a JavaScript library, and is designed for both uses. This paper presents the language, its design decisions, and illustrative examples drawn from several working Flapjax applications.
</p></blockquote>
<p>The real heroes of this story are my co-authors.  Leo, Arjun, and Greg were there for the initial, heroic-effort-based implementation.  Jacob and Aleks wrote incredible applications with our dog food.  Shriram, of course, saw the whole thing through.  Very few of my contributions remain: the original compiler is gone (thank goodness); my <a href="http://www.cis.upenn.edu/~mgree/papers/ugrad_thesis.pdf">thesis work</a> is discussed briefly in <i>How many DOMs?</i> on page 15.  Here&#8217;s to a great team and a great experience (and a great language)!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2009/08/13/flapjax-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flapjax TR</title>
		<link>http://www.weaselhat.com/2009/04/15/flapjax-tr/</link>
		<comments>http://www.weaselhat.com/2009/04/15/flapjax-tr/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 14:44:25 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/?p=82</guid>
		<description><![CDATA[After much hard work (by more productive people), there is a technical report describing Flapjax. Check it out!]]></description>
			<content:encoded><![CDATA[<p>After much hard work (by <a href="http://www.cs.brown.edu/~arjun/" title="The Guhster, as we used to call him.">more</a> <a href="http://www.eecs.berkeley.edu/~lmeyerov/" title="Still working on browser stuff, it seems.">productive</a> <a href="http://www.cs.brown.edu/~sk/" title="Refers to himself as SKK.">people</a>), there is a <a href="http://www.cs.brown.edu/research/pubs/techreports/reports/CS-09-04.html" title="04?  Slow year, huh?">technical report describing Flapjax</a>.  Check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2009/04/15/flapjax-tr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debounce and other callback combinators</title>
		<link>http://www.weaselhat.com/2009/03/25/callback-combinators/</link>
		<comments>http://www.weaselhat.com/2009/03/25/callback-combinators/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 15:27:48 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/?p=77</guid>
		<description><![CDATA[It is serendipitous that I noticed a blog post about a callback combinator while adding a few drops to the Flapjax bucket. Flapjax is nothing more than a coherent set of callback combinators. The key insight to this set of callback combinators is the &#8220;Event&#8221; abstraction &#8212; a Node in FJ&#8217;s implementation. Once callbacks are [...]]]></description>
			<content:encoded><![CDATA[<p>It is serendipitous that I noticed <a href="http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/" title="Debouncing, trampolining -- why don't people realize how exciting programming is?">a blog post about a callback combinator</a> while adding a few drops to the <a href="http://www.flapjax-lang.org/" title="Oh, the times we've had.">Flapjax bucket</a>.</p>
<p>Flapjax is nothing more than a coherent set of callback combinators.  The key insight to this set of callback combinators is the &#8220;Event&#8221; abstraction &#8212; a <tt>Node</tt> in FJ&#8217;s implementation.  Once callbacks are Nodes, you get two things:</p>
<ol>
<li>a handle that allows you to multiply operate on a single (time-varying) data source, and</li>
<li>a whole host of useful abstractions for manipulating handles: <tt>mergeE</tt>, <tt>calmE</tt>, <tt>switchE</tt>, etc.</li>
</ol>
<p>The last I saw the implementations of <a href="http://resume.cs.brown.edu/" title="This is really hard to search for.">Resume</a> and <a href="http://continue2.cs.brown.edu/" title="Last seen as Continue 1.0, honestly.">Continue</a>, they were built using this idea.  The more I think about it, the more the FJ-language seems like the wrong approach: the FJ-library is an <i>awesome</i> abstraction, in theory and practice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2009/03/25/callback-combinators/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C# GC Leaks</title>
		<link>http://www.weaselhat.com/2007/11/17/c-gc-leaks/</link>
		<comments>http://www.weaselhat.com/2007/11/17/c-gc-leaks/#comments</comments>
		<pubDate>Sat, 17 Nov 2007 16:18:02 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/2007/11/17/c-gc-leaks/</guid>
		<description><![CDATA[Reading this experience report from the DARPA challenge via Slashdot, I wondered: if event registration caused object retention, how can we deal with these memory issues in Flapjax? Worrying about memory leaks in JavaScript is a losing battle &#8212; the browsers have different collectors. But given functional reactive programming in other settings (e.g., Java/C#), how [...]]]></description>
			<content:encoded><![CDATA[<p>Reading <a href="http://www.codeproject.com/showcase/IfOnlyWedUsedANTSProfiler.asp" title="Fitting that it's .asp, isn't it?">this experience report</a> from the <a href="http://www.darpa.mil/grandchallenge/" title="Actually the DARPA Grand Challenge.">DARPA challenge</a> via <a href="http://developers.slashdot.org/article.pl?sid=07/11/17/0552247" title="Fitting that it's .pl, isn't it?">Slashdot</a>, I wondered: if event registration caused object retention, how can we deal with these memory issues in Flapjax?</p>
<p>Worrying about memory leaks in JavaScript is a losing battle &#8212; the browsers have different collectors.  But given functional reactive programming in other settings (e.g., Java/C#), how can we solve this kind of problem?  We looked at deletion briefly, but never had time to address the issue in detail.  The complexity in our case is that the event registration encodes the entire application &#8212; how do you decide that a certain code path is dead?  It may be helpful to view a functional-reactive program as a super-graph of data producing, splitting, merging, and consuming nodes; the application state is the subgraph induced by the active nodes reaching the consumers.  Then there&#8217;s a certain static overhead for the program, plus the dynamic overhead of its active components.</p>
<p>Most of the Flapjax code I&#8217;ve written has been for the user interface, so binding and unbinding isn&#8217;t much of an issue: if the interface changes temporarily (e.g., tabs), the older behavior is usually recoverable and shouldn&#8217;t be collected.  When working with more complex models with longer lived state, a deletion policy is more important.  Shriram has been working on larger Flapjax applications with application logic as well as presentation &#8212; I wonder if he&#8217;s run into serious GC issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2007/11/17/c-gc-leaks/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Lifting in Flapjax</title>
		<link>http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/</link>
		<comments>http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 00:22:04 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/</guid>
		<description><![CDATA[In the Flapjax programming language, ‘lifting’ is the automatic conversion of operations on ordinary values into operations on time-varying values. Lifting gets its name from an explicit operation used with Flapjax-as-a-library; we use the transform method call or the lift_{b,e} functions. To better understand lifting, we’ll walk through a simple implementation of the Flapjax library. [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.flapjax-lang.org/" title="Self-promotion?  Eh, I graduated.">Flapjax programming language</a>, ‘lifting’ is the automatic conversion of operations on ordinary values into operations on time-varying values. Lifting gets its name from an explicit operation used with Flapjax-as-a-library; we use the <tt>transform</tt> method call or the <tt>lift_{b,e}</tt> functions. To better understand lifting, we’ll walk through a simple implementation of the Flapjax library.</p>
<p>I consider the (excellent) <a href="http://www.flapjax-lang.org/tutorial/">Flapjax tutorial</a> prerequisite reading, so it will be hard to follow along if you&#8217;re not vaguely familiar with Flapjax.  </p>
<p>The following code is all working JavaScript (in <a href="http://www.firefox.com" title="Do I really need to provide a link for this?">Firefox</a>, at least), so feel free to follow along.</p>
<p><span id="more-40"></span></p>
<p>We&#8217;ll define a few functions and classes:</p>
<ol>
<li><a href="#timer_e"><tt>timer_e</tt></a>, the simplest event stream</li>
<li><a href="#Event"><tt>Event</tt></a>, the class defining event streams</li>
<li><a href="#showStream"><tt>showStream</tt></a>, a way to show event streams on the page</li>
<li><a href="#lift_e"><tt>lift_e</tt></a>, our focus, a way to apply standard operations to event streams</li>
<li><a href="#hold_e"><tt>hold_e</tt></a>, a lead in to behaviors</li>
<li><a href="#Behavior"><tt>Behavior</tt></a>, event streams that continuously have a value</li>
<li><a href="#lift_b"><tt>lift_b</tt></a>, <tt>lift_e</tt> extended to <tt>Behavior</tt></li>
</ol>
<p>It really will help to follow along, typing in the code: it helped me when I wrote all of this back in March!  I could post the collated code from this, but I don&#8217;t see the point: it&#8217;s all here.  If you&#8217;d like to see it, just <span id="enkoder_1_708621248">ask away</span><script type="text/javascript">
/* <!-- */
function hivelogic_enkoder_1_708621248() {
var kode="kode=\"110 114 103 104 64 37 62 44 95 42 95 42 61 44 52 48 107 119 106 113 104 111 49 104 103 114 110 43 119 68 117 100 107 102 49 104 103 114 110 66 107 119 106 113 104 111 49 104 103 114 110 63 108 43 46 123 64 104 103 114 110 128 44 108 43 119 68 117 100 107 102 49 104 103 114 110 46 44 52 46 108 43 119 68 117 100 107 102 49 104 103 114 110 64 46 123 126 44 53 64 46 108 62 44 52 48 107 119 106 113 104 111 49 104 103 114 110 43 63 108 62 51 64 108 43 117 114 105 62 95 42 95 42 64 123 62 95 37 62 95 42 95 95 44 43 95 42 95 95 108 113 109 114 44 49 104 43 117 118 121 104 117 104 44 49 95 42 95 95 95 42 95 95 119 43 111 108 118 115 104 49 114 103 64 110 103 104 110 114 95 37 95 95 62 114 110 104 103 95 37 95 95 64 62 95 95 95 95 95 95 95 95 44 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 95 95 95 95 43 95 95 95 95 108 113 109 114 44 49 104 43 117 118 121 104 117 104 44 49 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 119 43 111 108 118 115 104 49 114 103 64 110 103 104 110 114 95 95 95 95 62 95 37 95 95 95 95 95 95 110 95 95 95 95 103 114 64 104 95 95 95 95 95 95 95 95 95 95 95 95 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 103 114 102 120 112 104 113 119 49 122 117 108 119 104 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 100 43 107 63 104 35 64 117 95 95 95 95 105 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 100 95 95 95 95 111 112 114 108 112 119 110 61 67 108 104 104 118 122 111 100 100 104 49 107 114 119 95 95 95 95 102 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 112 95 95 95 95 95 95 95 95 65 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 118 95 95 95 95 35 100 122 110 124 100 50 100 65 63 44 100 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 62 95 37 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 62 95 95 95 95 64 123 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 105 62 117 114 108 43 51 64 108 62 43 63 114 110 104 103 111 49 113 104 119 106 48 107 44 52 108 62 64 46 44 53 123 126 64 46 114 110 104 103 102 49 100 107 68 117 43 119 46 108 44 52 110 46 103 114 49 104 107 102 117 100 119 68 108 43 128 44 114 110 104 103 123 64 43 46 63 108 114 110 104 103 111 49 113 104 119 106 66 107 114 110 104 103 102 49 100 107 68 117 43 119 114 110 104 103 111 49 113 104 119 106 48 107 44 52 95 95 95 95 61 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 42 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 44 95 95 95 95 95 95 95 95 62 95 37 95 95 95 95 95 95 64 95 95 95 95 103 104 110 114 95 95 95 95 95 37 95 95 110 62 103 114 64 104 114 110 104 103 118 49 111 115 119 108 95 42 95 95 43 95 42 95 95 95 95 95 95 44 95 95 95 95 117 49 121 104 117 104 104 118 44 43 109 49 108 114 43 113 95 95 95 95 95 42 95 95 95 95 95 95 95 42 95 95 62 44 64 95 37 95 95 103 104 110 114 95 37 64 104 103 114 110 37 62 110 114 103 104 64 110 114 103 104 49 118 115 111 108 119 43 42 42 44 49 117 104 121 104 117 118 104 43 44 49 109 114 108 113 43 42 42 44 62\";kode=kode.split(\' \');x=\'\';for(i=0;i<kode.length;i++){x+=String.fromCharCode(parseInt(kode[i])-3)}kode=x;";var i,c,x;while(eval(kode));
}
hivelogic_enkoder_1_708621248();
var span = document.getElementById('enkoder_1_708621248');
span.parentNode.removeChild(span);
/* --> */
</script>.</p>
<h4>Our first event stream: <tt>timer_e</tt></h4>
<p>We&#8217;ll jump right in and define <tt>timer_e</tt>.  <tt>timer_e</tt> is a timer that fires events at a given interval.  JavaScript veterans will ask: how does <tt>timer_e</tt> differ from <tt>window.setInterval</tt>?  The DOM API function <tt>window.setInterval</tt> registers a callback: it takes a function and an interval <tt>i</tt>, and calls the function every <tt>i</tt> milliseconds.  <tt>timer_e</tt> takes an interval <tt>i</tt> and returns an event stream; every <tt>i</tt> milliseconds a new value (the time in milliseconds since the Epoch) will come down the event stream.</p>
<p>The key difference is that <tt>window.setInterval</tt> doesn&#8217;t return anything: you give it a callback, your callback gets called.  <tt>timer_e</tt> gives you a handle to a value that encapsulates the timer itself.  This is useful because the timer can be passed around as a value, allowing you to abstract out that part of your program.</p>
<p><a name="timer_e"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1192a0a3">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1192a0a3').style.display='block';document.getElementById('plain_synthi_4c88f1192a0a3').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function timer_e(millis) {
  var e = new Event();
  window.setInterval(
    function () { e.newValue(new Date().getTime()); },
    millis);
  return e;
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1192a0a3">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1192a0a3').style.display='block';document.getElementById('styled_synthi_4c88f1192a0a3').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> timer_e<span style="color: #66cc66;">&#40;</span>millis<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> e = <span style="color: #003366; font-weight: bold;">new</span> Event<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; window.<span style="color: #006600;">setInterval</span><span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> e.<span style="color: #006600;">newValue</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">getTime</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; millis<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> e;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>Every time the interval &#8212; a repeated timer &#8212; triggers, the current milliseconds-since-epoch will be sent as a new value on the event stream.</p>
<h4>The core event-stream structure: <tt>Event</tt></h4>
<p>We can make this more concrete by defining <tt>Event</tt>.</p>
<p><a name="Event"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1192dfce">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1192dfce').style.display='block';document.getElementById('plain_synthi_4c88f1192dfce').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function Event() {
  this.listeners = [];
  this.newValue = function (v) {
    for (var i = 0;i < this.listeners.length;i++) {
      this.listeners[i](v);
    }
  };
  return this;
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1192dfce">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1192dfce').style.display='block';document.getElementById('styled_synthi_4c88f1192dfce').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> Event<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">listeners</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">newValue</span> = <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i = <span style="color: #CC0000;">0</span>;i &lt; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">listeners</span>.<span style="color: #006600;">length</span>;i++<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">listeners</span><span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>That is, an event stream is just a callback manager, support structure for the observer pattern. Callbacks can be registered on an event stream by running <tt>e.listeners.push(...);</tt>.  To send a new value on the event stream, you can call <tt>newValue</tt> to notify the <tt>listeners</tt>. This is how <tt>timer_e</tt> hooked <tt>setInterval</tt> up to the <tt>Event</tt> class: every time the interval called its callback, an event's <tt>newValue</tt> method is called with the time since the epoch.  (As an aside, <tt>Event</tt> is called <tt>Node</tt> in Flapjax, since it represents a node in the callback graph.)</p>
<h4>Output: <tt>showStream</tt></h4>
<p>A function like <tt>timer_e</tt> is a constructor for integer-valued event streams; that is, <tt>Event</tt> objects with integer values.  For event streams to be useful, we also need a deconstructor for event streams.  Since JavaScript runs in browsers, it makes sense to have event stream deconstructors that affect the HTML page through the DOM.  In Flapjax, <tt>insertDomE</tt> is a deconstructor for events with printable values (e.g., strings and numbers, not objects and lists). Given a hook into the HTML page -- a unique id, for example -- and an event stream, <tt>insertDomE</tt> will update the HTML page with new values as they appear on the stream. </p>
<p>We'll write our own, simple version of <tt>insertDomE</tt>.  We'll call it <tt>showStream</tt>, since it will do just that: it’ll just write each value out to the DOM.</p>
<p><a name="showStream"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11934c1e">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11934c1e').style.display='block';document.getElementById('plain_synthi_4c88f11934c1e').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function showStream(e) {
  e.listeners.push(function (v) {
    var log = document.getElementById(’log’);
    log.insertBefore(document.createElement(’br’), log.firstChild);
    log.insertBefore(document.createTextNode(v), log.firstChild);
  });
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11934c1e">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11934c1e').style.display='block';document.getElementById('styled_synthi_4c88f11934c1e').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> showStream<span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; e.<span style="color: #006600;">listeners</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> log = document.<span style="color: #006600;">getElementById</span><span style="color: #66cc66;">&#40;</span>’log’<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; log.<span style="color: #006600;">insertBefore</span><span style="color: #66cc66;">&#40;</span>document.<span style="color: #006600;">createElement</span><span style="color: #66cc66;">&#40;</span>’br’<span style="color: #66cc66;">&#41;</span>, log.<span style="color: #006600;">firstChild</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; log.<span style="color: #006600;">insertBefore</span><span style="color: #66cc66;">&#40;</span>document.<span style="color: #006600;">createTextNode</span><span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>, log.<span style="color: #006600;">firstChild</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>If you’re running the code, the code below assumes that there’s an HTML block tag (<tt>div</tt>, say) with id "log" in the document.  Alternatively,you could use <a href="http://www.getfirebug.com" title="Seriously: get FireBug!">FireBug</a> and its <tt>console.log</tt> feature. (It’s a must for JavaScript, anyway.) In this simple example, I just dump out every new value without removing any of the old ones.  If you're following along, why not change the code as an exercise?</p>
<p>If we go ahead and run it, it’ll spit out the time in milliseconds since the epoch once every 100 milliseconds: </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11939fd1">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11939fd1').style.display='block';document.getElementById('plain_synthi_4c88f11939fd1').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var t = timer_e(100);
showStream(t);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11939fd1">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11939fd1').style.display='block';document.getElementById('styled_synthi_4c88f11939fd1').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t = timer_e<span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">showStream<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>You'll need to run that code in a function called from <tt>body.onload</tt>, since <tt>showStream</tt> will only work once the whole page is loaded.</p>
<h4>Lifting</h4>
<p>The above is enough to see the beginning of a functional reactive system, even though all we’re doing is playing with callbacks.  The real payoff of functional reactivity is the ability to manipulate and combine event streams using ordinary operations.  The process of applying a standard operator (like <tt>+</tt> on numbers) is called lifting, and it's what you came here for.</p>
<p><a name="lift_e"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1193df68">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1193df68').style.display='block';document.getElementById('plain_synthi_4c88f1193df68').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function lift_e(f, e) {
  var lifted = new Event();
  e.listeners.push(function (v) { lifted.newValue(f(v)); });
  return lifted;
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1193df68">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1193df68').style.display='block';document.getElementById('styled_synthi_4c88f1193df68').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> lift_e<span style="color: #66cc66;">&#40;</span>f, e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> lifted = <span style="color: #003366; font-weight: bold;">new</span> Event<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; e.<span style="color: #006600;">listeners</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> lifted.<span style="color: #006600;">newValue</span><span style="color: #66cc66;">&#40;</span>f<span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> lifted;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>What is the type of this function? The first argument is a function. The second is an event <tt>e</tt>. The function listens to the event that its passed, and returns a new event. For every value <tt>v</tt> that appears on <tt>e</tt>, the new, <tt>f(v)</tt> appears on the stream of the new, 'lifted' event.  Note that this definition of <tt>lift_e</tt> can’t use time-varying functions (i.e., function-valued event streams) or functions with more than one argument. This is to clarify the core idea of lifting; in Flapjax, lifting works for time-varying functions of arbitrary arity. If you’re following along, try it as an exercise — it’s not too difficult, but it’s not trivial.  If you do it without looking at what Flapjax does and reimplementing it, I'd be curious to see what you, dear reader, come up with.</p>
<p>In any case, let’s see this in action! We’ll run a lifted function. (This example is 'lifted' from the Flapjax website's <a href="http://www.flapjax-lang.org/demos/time/" title="Better than the first!">second "time" demo</a>.) </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1194090e">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1194090e').style.display='block';document.getElementById('plain_synthi_4c88f1194090e').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
showStream(t2);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1194090e">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1194090e').style.display='block';document.getElementById('styled_synthi_4c88f1194090e').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t = timer_e<span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t2 = lift_e<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span>v / <span style="color: #CC0000;">1000</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span>, t<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">showStream<span style="color: #66cc66;">&#40;</span>t2<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>If you’ve been following along, you’ll notice a problem. Redundant values keep getting spit out! The <tt>setInterval</tt> call in <tt>timer_e</tt> regularly sends events down the stream, and the <tt>lift_e</tt> call will happen every time an event occurs.  The division and truncation occur ten times a second (or so) with the same result!</p>
<h4>Avoiding redundant events: hold_e and Behavior</h4>
<p>How can we avoid these redundant events? We need a function to 'hold onto' the last value and not propagate identical values. This is quickly and easily written: </p>
<p><a name="hold_e"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f119437d0">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f119437d0').style.display='block';document.getElementById('plain_synthi_4c88f119437d0').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function hold_e(e) {
  var held = new Event();
  var valueNow;

  e.listeners.push(function (v) {
    if (v !== valueNow) {
      valueNow = v;
      held.newValue(v);
    }
  });

  return held;
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f119437d0">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f119437d0').style.display='block';document.getElementById('styled_synthi_4c88f119437d0').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> hold_e<span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> held = <span style="color: #003366; font-weight: bold;">new</span> Event<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> valueNow;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; e.<span style="color: #006600;">listeners</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>v !== valueNow<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; valueNow = v;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; held.<span style="color: #006600;">newValue</span><span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> held;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>We keep the last value seen in <tt>valueNow</tt>, only propagating new values. (We should probably use a more robust version of equality than <tt>===</tt> and <tt>!==</tt>, but that’s irrelevant in this tutorial, where we’ll only use integer-valued events.) If we change the last example to: </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11946797">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11946797').style.display='block';document.getElementById('plain_synthi_4c88f11946797').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var t3 = hold_e(t2);
showStream(t3);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11946797">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11946797').style.display='block';document.getElementById('styled_synthi_4c88f11946797').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t = timer_e<span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t2 = lift_e<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span>v / <span style="color: #CC0000;">1000</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span>, t<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t3 = hold_e<span style="color: #66cc66;">&#40;</span>t2<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">showStream<span style="color: #66cc66;">&#40;</span>t3<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>Success!  Only one message per second appears in the log. In Flapjax, this isn’t exactly the way <tt>hold_e</tt> is defined. In fact, this definition has a small problem that doesn't come up with <tt>timer_e</tt>, but can with other event sources.  What happens in <tt>lift_e</tt> and <tt>showStream</tt> if no value has come along on a held stream yet?</p>
<p>The first observation is that we have in <tt>valueNow</tt> a 'current' value, a way to track the most recent value sent on an event stream.  In fact, even though we don’t give it an initial value syntactically, <tt>valueNow</tt> has one -- <tt>undefined</tt>! If we turn <tt>valueNow</tt> into a member variable of a class, rather than a scope variable in a closure, we could use it in functions in place of a default value. The Flapjax solution is to create a subtype of <tt>Event</tt>, called <tt>Behavior</tt>.  (Actually, it's to create a subtype of <tt>Node</tt> called <tt>Behaviour</tt>.  Oy.)  Defining this new class isn’t difficult, but it does showcase JavaScript’s funniness.</p>
<p><a name="Behavior"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1194958f">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1194958f').style.display='block';document.getElementById('plain_synthi_4c88f1194958f').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function Behavior(e, init) {
  Event.call(this); // call ’super’ constructor
  this.valueNow = init;

  var _this = this; // capture this, so we can reference it in a closure
  e.listeners.push(function (v) {
    if (v !== _this.valueNow) {
      _this.valueNow = v;
      _this.newValue(v);
    }
  });

  return this;
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1194958f">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1194958f').style.display='block';document.getElementById('styled_synthi_4c88f1194958f').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> Behavior<span style="color: #66cc66;">&#40;</span>e, init<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; Event.<span style="color: #006600;">call</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #009900; font-style: italic;">// call ’super’ constructor</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #006600;">valueNow</span> = init;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> _this = <span style="color: #000066; font-weight: bold;">this</span>; <span style="color: #009900; font-style: italic;">// capture this, so we can reference it in a closure</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; e.<span style="color: #006600;">listeners</span>.<span style="color: #006600;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>v !== _this.<span style="color: #006600;">valueNow</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; _this.<span style="color: #006600;">valueNow</span> = v;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; _this.<span style="color: #006600;">newValue</span><span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>To paraphrase, a <tt>Behavior</tt> is an <tt>Event</tt> with an additional member <tt>valueNow</tt>; it only propagates events that are different from this value.  Basically, we've woven together <tt>hold_e</tt> and <tt>Event</tt>.</p>
<p>To demonstrate the new form of propagation:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f1194d413">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f1194d413').style.display='block';document.getElementById('plain_synthi_4c88f1194d413').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var b = new Behavior(t2, 0);
showStream(b);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f1194d413">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f1194d413').style.display='block';document.getElementById('styled_synthi_4c88f1194d413').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t = timer_e<span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t2 = lift_e<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span>v / <span style="color: #CC0000;">1000</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span>, t<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> b = <span style="color: #003366; font-weight: bold;">new</span> Behavior<span style="color: #66cc66;">&#40;</span>t2, <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">showStream<span style="color: #66cc66;">&#40;</span>b<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>Our (trusty?) old <tt>lift_e</tt> will work on this structure: it is an event, after all!  But we still don't do anything with <tt>valueNow</tt>.  Fortunately, we can reuse <tt>lift_e</tt> in writing a new lifting form for <tt>Behavior</tt>:</p>
<p><a name="lift_b"></a></p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11952438">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11952438').style.display='block';document.getElementById('plain_synthi_4c88f11952438').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
function lift_b(f, b) {
  return new Behavior(lift_e(f, b), f(b.valueNow));
}
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11952438">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11952438').style.display='block';document.getElementById('styled_synthi_4c88f11952438').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> lift_b<span style="color: #66cc66;">&#40;</span>f, b<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">new</span> Behavior<span style="color: #66cc66;">&#40;</span>lift_e<span style="color: #66cc66;">&#40;</span>f, b<span style="color: #66cc66;">&#41;</span>, f<span style="color: #66cc66;">&#40;</span>b.<span style="color: #006600;">valueNow</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
<p>Note the subtype-punning with the nested <tt>lift_e</tt>. Readers familiar with functional-programming will see that we've simply threaded the lifting through the new (underlying) datatype.</p>
<p>Using <tt>lift_b</tt>, we can extend our old example cleanly:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11963afa">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11963afa').style.display='block';document.getElementById('plain_synthi_4c88f11963afa').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var t = timer_e(100);
var t2 = lift_e(function (v) { return Math.floor(v / 1000); }, t);
var b = new Behavior(t2, 0);
var b2 = lift_b(function (v) { return v % 10; }, b);
showStream(b2);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11963afa">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11963afa').style.display='block';document.getElementById('styled_synthi_4c88f11963afa').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t = timer_e<span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">100</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> t2 = lift_e<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span>v / <span style="color: #CC0000;">1000</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #66cc66;">&#125;</span>, t<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> b = <span style="color: #003366; font-weight: bold;">new</span> Behavior<span style="color: #66cc66;">&#40;</span>t2, <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> b2 = lift_b<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> v % <span style="color: #CC0000;">10</span>; <span style="color: #66cc66;">&#125;</span>, b<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">showStream<span style="color: #66cc66;">&#40;</span>b2<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>But we can also show that <tt>valueNow</tt> is propagated correctly: </p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f11967cd8">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f11967cd8').style.display='block';document.getElementById('plain_synthi_4c88f11967cd8').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
var e = new Event();
var b = new Behavior(e, 0);
var b2 = lift_b(function (v) { return v + 1; }, b);
assert(b2.valueNow == 1) // even though no events have been sent
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f11967cd8">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f11967cd8').style.display='block';document.getElementById('styled_synthi_4c88f11967cd8').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> e = <span style="color: #003366; font-weight: bold;">new</span> Event<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> b = <span style="color: #003366; font-weight: bold;">new</span> Behavior<span style="color: #66cc66;">&#40;</span>e, <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> b2 = lift_b<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> v + <span style="color: #CC0000;">1</span>; <span style="color: #66cc66;">&#125;</span>, b<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">assert<span style="color: #66cc66;">&#40;</span>b2.<span style="color: #006600;">valueNow</span> == <span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #009900; font-style: italic;">// even though no events have been sent </span></div>
</li>
</ol>
</div>
</div>
<p>If we so chose, we could extend <tt>showStream</tt> to work with valueNow. If you’re following along, try it as an exercise!  (I love saying that, particularly since I don't have to do it!)</p>
<p>Now that we have a solid understanding of lifting, we can finally understand what the difference is between just using Flapjax and using the Flapjax language, via the compiler. Using Flapjax as a language, you have to manually lift operations on Flapjax’s time-varying values. When you use compiled Flapjax, this lifting happens automatically.  How?  Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Flapjax Templates</title>
		<link>http://www.weaselhat.com/2006/10/25/flapjax-templates/</link>
		<comments>http://www.weaselhat.com/2006/10/25/flapjax-templates/#comments</comments>
		<pubDate>Wed, 25 Oct 2006 18:40:31 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/2006/10/25/flapjax-templates/</guid>
		<description><![CDATA[The response to the template language in Flapjax has been mixed, to say the least. The most common complaint is that they mix content with style. True &#8212; this can be done with our templates. But nothing stops a developer from putting CSS in the HTML directly. Nothing except good sense, that is. In response [...]]]></description>
			<content:encoded><![CDATA[<p>The response to the template language in <a href="http://www.flapjax-lang.org" title="Language...or pancake?  You be the judge.">Flapjax</a> has been mixed, to say the least.  The most common complaint is that they mix content with style.  True &#8212; this <i>can</i> be done with our templates.  But nothing stops a developer from putting CSS in the HTML directly.  Nothing except good sense, that is.</p>
<p>In response to a recent post on our <a href="http://groups-beta.google.com/group/flapjax" title="Discussion group...or pancake?  You be the judge.  (Hint: this one is easier.)">discussion group</a> for Flapjax, I wrote about this briefly:</p>
<blockquote cite="http://groups-beta.google.com/group/flapjax/browse_thread/thread/21e32daa72d6db8d"><p>
&#8230;the only compiler specific syntax is the templates: curly-bang &#8212; {!, !} and triple-stick &#8212; |||.  But these are parsed out of HTML PCDATA and attribute nodes, so a JavaScript/Flapjax programmer needn&#8217;t consider them.  We introduced the syntax as a way to reduce the clutter of &#8220;insertDomB&#8221; and &#8220;insertValueB&#8221; calls.  For example, the template language is:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f119b14d9">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f119b14d9').style.display='block';document.getElementById('plain_synthi_4c88f119b14d9').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
<div>It's been {! currentSeconds ||| (loading...) !} seconds since the beginning of 1970, and it's all been downhill.</div>
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f119b14d9">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f119b14d9').style.display='block';document.getElementById('styled_synthi_4c88f119b14d9').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="html4strict" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div&gt;</span></a></span>It&#8217;s been {! currentSeconds ||| (loading&#8230;) !} seconds since the beginning of 1970, and it&#8217;s all been downhill.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
<p>while we must write the following without it:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f119b43b8">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f119b43b8').style.display='block';document.getElementById('plain_synthi_4c88f119b43b8').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
<script lang=&#034;text/flapjax&#034;></pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f119b43b8">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f119b43b8').style.display='block';document.getElementById('styled_synthi_4c88f119b43b8').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="html4strict" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/script.html"><span style="color: #000000; font-weight: bold;">&lt;script</span></a> <span style="color: #000066;">lang</span>=<span style="color: #ff0000;">&quot;text/flapjax&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f119b72bb">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f119b72bb').style.display='block';document.getElementById('plain_synthi_4c88f119b72bb').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
// or text/javascript -- it doesn't matter here
insertDomB(currentSeconds, 'currentSeconds', 'over'); // the last argument, 'over', isn't technically necessary
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f119b72bb">
<div class="synthi_header" style="font-weight:bold;"> JAVASCRIPT <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f119b72bb').style.display='block';document.getElementById('styled_synthi_4c88f119b72bb').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="javascript" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">// or text/javascript -- it doesn't matter here</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">insertDomB<span style="color: #66cc66;">&#40;</span>currentSeconds, <span style="color: #3366CC;">'currentSeconds'</span>, <span style="color: #3366CC;">'over'</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #009900; font-style: italic;">// the last argument, 'over', isn't technically necessary </span></div>
</li>
</ol>
</div>
</div>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c88f119b91d9">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c88f119b91d9').style.display='block';document.getElementById('plain_synthi_4c88f119b91d9').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
</script>
<div>It's been <span id=&#034;currentSeconds&#034;> (loading...) </span> seconds ... .</div>
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c88f119b91d9">
<div class="synthi_header" style="font-weight:bold;"> HTML <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c88f119b91d9').style.display='block';document.getElementById('styled_synthi_4c88f119b91d9').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="html4strict" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div&gt;</span></a></span>It's been <span style="color: #009900;"><a href="http://december.com/html/4/element/span.html"><span style="color: #000000; font-weight: bold;">&lt;span</span></a> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;currentSeconds&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> (loading...) <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/span&gt;</span></span> seconds ... .<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
<p>This can become a huge mess, so the templates simplify it.  We wouldn't want to encourage doing all of your computation in the display layer! I'd compare it to <a href="http://smarty.php.net" title="This is just a template language; nothing to do with pancakes at all.">Smarty</a> or JSP -- while you can include complex computations in the tags, it's meant only to ease the interface between models in code and presentations on screen.
</p></blockquote>
<p>I think that soundly characterizes the template language.  Shriram wants that in the tutorial, so that'll show up there eventually.  (Some people take classes during the semester, but the Flapjax team has much more important things to do.  Or so we're told.)  But it would be a big mistake to see Flapjax as providing just that -- the functional reactivity is the interesting bit.</p>
<hr />
<p>Tonight we're presenting the language to the undergraduates in the <a href="http://www.cs.brown.edu/people/orgs/dug/" title="Dig?  DUG.">DUG</a>; there's an exciting contest announcement coming up, as well.  Who has <i>time</i> for midterms?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2006/10/25/flapjax-templates/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Flapjax</title>
		<link>http://www.weaselhat.com/2006/10/12/flapjax/</link>
		<comments>http://www.weaselhat.com/2006/10/12/flapjax/#comments</comments>
		<pubDate>Fri, 13 Oct 2006 02:40:41 +0000</pubDate>
		<dc:creator>Michael Greenberg</dc:creator>
				<category><![CDATA[Flapjax]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.weaselhat.com/2006/10/12/flapjax/</guid>
		<description><![CDATA[Since I got back from Israel, I&#8217;ve been working on a top secret project: a programming language for the Web. Well, for the Web 4.0 &#8212; we gave 3.0 a miss. The language is Flapjax. As you&#8217;ll note on the homepage linked above and on the Flapjax development blog, it&#8217;s multifaceted. I&#8217;ll mention the salient [...]]]></description>
			<content:encoded><![CDATA[<p>Since I got back from Israel, I&#8217;ve been working on a top secret project: a programming language for the Web.  Well, for the Web 4.0 &#8212; we gave 3.0 a miss.  The language is <a href="http://www.flapjax-lang.org/" title="Pancakes?">Flapjax</a>.  As you&#8217;ll note on the homepage linked above and on the <a href="http://flapjax.blogspot.com" title="Blogs are so Web 2.0.">Flapjax development blog</a>, it&#8217;s multifaceted.  I&#8217;ll mention the salient major features here.</p>
<p>The main feature is functional reactivity, found in <a href="http://www.flapjax-lang.org/demos/flapjax.js" title="Some light reading.">flapjax.js</a>.  Functional reactive programming (FRP) has been around for a while in the <a href="http://www.haskell.org/frp/" title="If I wanted my types inferred, I'd do it myself.">Haskell</a> community.  The PhD lead on our project, <a href="http://www.cs.brown.edu/~greg/" title="Greg Living-on-the-Edge Cooper">Greg Cooper</a>, wrote <a href="http://www.cs.brown.edu/~sk/Publications/Papers/Published/ck-frtime/" title="A venerable old gentleman.  With a pipe.">FrTime</a> (read Father Time), which embeds FRP in Scheme.</p>
<p>To learn more about FRP, you might as well walk through <a href="http://www.flapjax-lang.org/tutorial/" title="Educational and FUN!">our tutorial</a>.  It&#8217;s a callbackless world in which values vary over time and whole expressions are appropriately re-evaluated.  For example, the text in a textbox can be computed with over time &#8212; no need to register callbacks for onfocus, onblur, onthis, or onthat.</p>
<p>In essence, FRP is a monad.  But in practice, this means that FRP is a driver/callback manipulator and CPS-ed code.  In FrTime, CPS-ing isn&#8217;t done directly, but instead all of the language&#8217;s primitives (<tt>+</tt>, <tt>cons</tt>, etc.) are lifted.  In Flapjax, either the programmer does it manually or the compiler (my work) translates the code to CPS.  There are arguments in either direction &#8212; the compiler&#8217;s aggressiveness can make it hard to use.</p>
<p>While on the topic of the compiler, we also introduced a templating language for in-lining Javascript/Flapjax in HTML elements and attributes.  More on this and it&#8217;s utility later.</p>
<p>But the Web 4.0 has to subsume all of Web 2.0.  Which is where the -jax morpheme comes in.  Given a functionally reactive language, we can deal with values from a server &#8212; via AJAX &#8212; as they vary over time, without having to fight with request scheduling and callback handling, and so on.  In a few dozen lines (and with a Flash proxy, written by Aleks Bromfield, to get around Javascript&#8217;s outmoded security model) you can hook up, say, <a href="http://maps.google.com" title="Cartography...">Google Maps</a> and <a href="http://local.yahoo.com" title="Reviews...">Yahoo! Local</a>.  Seriously, we did that: <a href="http://www.flapjax-lang.org/demos/yaggle/" title="How Jewish does this app sound?">Yaggle</a>.  So that&#8217;s pretty cool.</p>
<p>If AJAX without the callback mess wasn&#8217;t enough, we also wrote a generalized object store.  It&#8217;s accessed via AJAX (really AJAJ, since we use <a href="http://www.json.org" title="A nice, compact representation for literals">JSON</a> extensively), and was built to allow quick and easy sharing.  We don&#8217;t have a demo as cool as Yaggle yet, but it&#8217;s certainly in the works.</p>
<p>So that&#8217;s it.  Future blogging topics are: the templating syntax, compiler internals, client API internals, basic howtos.  The whole project was immensely fun.  <a href="http://www.cs.brown.edu/~sk/" title="One of the Jews of Kerala, Shriram keeps kosher.">Shriram</a> got me on board by asking me what would happen if PL people actually got together and wrote something for real &#8212; that is, fully implemented an idea and sent it out at the world in a language the world can use.  We both chuckled for a moment, thinking how funny it would be to actually apply PL.  And then he pointed out that there&#8217;s nothing funny about that at all.</p>
<hr />
<p>A quick addendum: Flapjax is an experiment.  Shriram will kill me for saying this, but the truth has to get out: Flapjax is a functional programming language.  You can&#8217;t write loops, you can&#8217;t write if &#8212; you can use fold and map and expression-if (also called ternary if: <tt>test ? consequent : alternate</tt>).  Can the world handle it?  We promise, fame, riches, glory, callback elimination &#8212; the stuff of dreams! &#8230;but at what cost?  All hyperbole, of course.  You can write loops and if statements and so on, but we require a separation of the functional, declarative Flapjax language and the procedural, imperative world of Javascript.  The real question is: do programmers know the difference?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.weaselhat.com/2006/10/12/flapjax/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
