<?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/"
	>

<channel>
	<title>Left Right Fold</title>
	<atom:link href="http://leftrightfold.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://leftrightfold.com</link>
	<description>Conventional programs consist of 90% assignment statements</description>
	<pubDate>Sun, 06 Dec 2009 19:09:07 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The death of if-else, if, and else</title>
		<link>http://leftrightfold.com/?p=85</link>
		<comments>http://leftrightfold.com/?p=85#comments</comments>
		<pubDate>Sun, 06 Dec 2009 03:00:21 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Functional Programming]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=85</guid>
		<description><![CDATA[Conditional branches are like a piece of meat in the source code; as the software ages, the meat starts to rot.  Before you know it, maggots (bugs) will start to feast on the meat.
One of the main reasons bugs tend to hide around conditional branches is because it increases the complexity of the software.  The [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>Conditional branches are like a piece of meat in the source code; as the software ages, the meat starts to rot.  Before you know it, maggots (bugs) will start to feast on the meat.</strong></p></blockquote>
<p>One of the main reasons bugs tend to hide around conditional branches is because it increases the complexity of the software.  The more conditional branching exists, the more difficult it is to fit all the logic into one&#8217;s head.  This is obvious, and I can probably talk all day on how bugs can be introduced with conditional branching, but let&#8217;s not dwell on that.  Instead let&#8217;s talk about how we can solve the problem in a simple way.</p>
<p><img class="aligncenter size-full wp-image-88" title="switch_board" src="http://leftrightfold.com/wp-content/uploads/2009/12/switch_board.jpg" alt="switch_board" width="500" height="333" /></p>
<p>The dispatch table pattern is not new, but I feel like it is not widely adopted.  It is not a traditional design pattern one will find in a typical design pattern book, but in my opinion this pattern will give you the most bang for the buck.  With a dispatch table, branching statements can be eliminated completely, and the &#8220;shape&#8221; of the code can be seen.  In the simplest form, a dispatch table is a hash table where all the keys represent all possible actions, and the value of each key contains a call back function that does the actual work.</p>
<p>This is best explained with a simple example.  I am going to use JavaScript in the example, but the idea is language independent.</p>
<p>Let&#8217;s say, you are building a Tivo&#8217;ish program that surfs all the channels and figures out what it should record.  Assuming an external data feed look like following:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> channels <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #CC0000;">1</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> station<span style="color: #339933;">:</span>   <span style="color: #3366CC;">&quot;NBC&quot;</span><span style="color: #339933;">,</span>
         showTitle<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Saturday Night Live&quot;</span><span style="color: #339933;">,</span>
         genre<span style="color: #339933;">:</span>     <span style="color: #3366CC;">&quot;comedy&quot;</span><span style="color: #339933;">,</span>
         repeat<span style="color: #339933;">:</span>    <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #CC0000;">2</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> station<span style="color: #339933;">:</span>   <span style="color: #3366CC;">&quot;FOX&quot;</span><span style="color: #339933;">,</span>
         showTitle<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Cops&quot;</span><span style="color: #339933;">,</span>
         genre<span style="color: #339933;">:</span>     <span style="color: #3366CC;">&quot;crime&quot;</span><span style="color: #339933;">,</span>
         repeat<span style="color: #339933;">:</span>    <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #CC0000;">3</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> station<span style="color: #339933;">:</span>   <span style="color: #3366CC;">&quot;ESPN&quot;</span><span style="color: #339933;">,</span>
         showTitle<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;College Football&quot;</span><span style="color: #339933;">,</span>
         genre<span style="color: #339933;">:</span>     <span style="color: #3366CC;">&quot;football&quot;</span><span style="color: #339933;">,</span>
         repeat<span style="color: #339933;">:</span>    <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #CC0000;">4</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> station<span style="color: #339933;">:</span>   <span style="color: #3366CC;">&quot;HBO&quot;</span><span style="color: #339933;">,</span>
         showTitle<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Curb Your Enthusiasm&quot;</span><span style="color: #339933;">,</span>
         genre<span style="color: #339933;">:</span>     <span style="color: #3366CC;">&quot;comedy&quot;</span><span style="color: #339933;">,</span>
         repeat<span style="color: #339933;">:</span>    <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>The key for the channels hash table is a channel number.  In this case, there are only 4 channels, one through four.  Let&#8217;s move on to the core logic:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> record<span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// do some work here...</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;recording &quot;</span> <span style="color: #339933;">+</span> channel.<span style="color: #660066;">showTitle</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> surf<span style="color: #009900;">&#40;</span>channels<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> genre<span style="color: #339933;">,</span> repeat<span style="color: #339933;">,</span> showTitle;
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> number <span style="color: #000066; font-weight: bold;">in</span> channels<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        genre      <span style="color: #339933;">=</span> channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">genre</span>;
        repeat     <span style="color: #339933;">=</span> channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">repeat</span>;
        showTitle <span style="color: #339933;">=</span> channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">showTitle</span>;
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>genre <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;football&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            record<span style="color: #009900;">&#40;</span>channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>genre <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;comedy&quot;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>repeat<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            record<span style="color: #009900;">&#40;</span>channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>genre <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;crime&quot;</span> <span style="color: #339933;">&amp;&amp;</span> showTitle <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;Cops&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            record<span style="color: #009900;">&#40;</span>channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The code above is making decisions on the genre of the show with a couple of ugly else-if statements.  As one can imagine, the else-if statement will continue to grow when additional functionality is required and eventually becomes unmanageable.  Imagine what the unit test for this function looks like. Yuck!</p>
<p>Now let&#8217;s switch to the dispatch table version:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> actions <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;football&quot;</span><span style="color: #339933;">:</span>  <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> record<span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;comedy&quot;</span>  <span style="color: #339933;">:</span>  <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>channel.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> record<span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;crime&quot;</span>   <span style="color: #339933;">:</span>  <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>channel.<span style="color: #660066;">showTitle</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;Cops&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> record<span style="color: #009900;">&#40;</span>channel<span style="color: #009900;">&#41;</span>; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span>;
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> surf_dispatch<span style="color: #009900;">&#40;</span>channels<span style="color: #339933;">,</span> actions<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> genre;
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> number <span style="color: #000066; font-weight: bold;">in</span> channels<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        genre <span style="color: #339933;">=</span> channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">genre</span>;
        actions<span style="color: #009900;">&#91;</span>genre<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>channels<span style="color: #009900;">&#91;</span>number<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>An actions dispatch table has been added as a parameter, and all the conditional branch logic has been completely removed.  Notice how simple the new surf function has become.  Now this version is very easy to extend because the application logic has been decoupled from structural logic.  To make things even better, the actions dispatch table is essentially a configuration point for the application.  There is an anonymous function with one parameter associated with each key, that is the interface each dispatch item must implement.  The application will start to behave differently when the table has been updated.  New behavior can be injected without changing any core code.  Now, that&#8217;s flexibility!</p>
<p>Skeptics may say, that problem has been solved in the Object Oriented world by polymorphism.  There are known refactoring steps to deal with this: <strong>Extract Method, Move Method, Replace Type Code with Subclasses</strong> then finally <strong>Replace Conditional with Polymorphism</strong>.  Wow, that is a lot of work, and think about the number of classes and lines of code you will end up with!  I will take the dispatch table pattern any day.</p>
<p>Dispatch table is one of those hidden gem design patterns, that will allow the software to be extended in ways never imagined.  The application behavior can be completely changed by supplying new anonymous functions to the dispatch table.  If you are working in a dynamic language, the dispatch table can live in a separate &#8220;configuration&#8221; file, and be read during run-time.</p>
<p>I have only scratched the surface on what you can do with a dispatch table. <a id="kizd" title="Chapter 2 of Higher-Order Perl by Mark Jason Dominus" href="http://hop.perl.plover.com/book/">Chapter 2 of Higher-Order Perl by Mark Jason Dominus</a> has a much more comprehensive overview of dispatch tables.  The book is currently available as a free download, so there is no reason not to check it out.  Don&#8217;t be afraid if you are not familiar or a fan of Perl, the book is readable with very little Perl knowledge.</p>
<p>I would also like to give a special thanks to my friend, and colleague, <a id="zlms" title="Kyle Burton" href="http://asymmetrical-view.com/">Kyle Burton</a>, for recommending the book.  It forever changed how I think.</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=85</wfw:commentRss>
		</item>
		<item>
		<title>test-expect Contribution</title>
		<link>http://leftrightfold.com/?p=82</link>
		<comments>http://leftrightfold.com/?p=82#comments</comments>
		<pubDate>Mon, 13 Jul 2009 02:00:39 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Clojure]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=82</guid>
		<description><![CDATA[test-expect is a expectation mocking framework for Clojure.  It is very easy to use and it hooks the result reporting into test-is, the standard Clojure xUnit testing framework that is part of Clojure Contrib (Now clojure.test).  This post is not a test-expect tutorial, but about a minor suggestion I made to Matt Clark, the author of test-expect.
Before [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/test-expect/" target="_blank">test-expect</a> is a expectation mocking framework for Clojure.  It is very easy to use and it hooks the result reporting into test-is, the standard Clojure xUnit testing framework that is part of Clojure Contrib (Now clojure.test).  This post is not a test-expect tutorial, but about a minor suggestion I made to Matt Clark, the author of test-expect.</p>
<p>Before I explain the suggestion I made, it is useful to walk through a simple example.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn awesome <span style="color: #66cc66;">&#91;</span>a b c<span style="color: #66cc66;">&#93;</span> a<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>defn what<span style="color: #66cc66;">-</span>is <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>awesome <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>deftest should<span style="color: #66cc66;">-</span>be<span style="color: #66cc66;">-</span>awesome
  <span style="color: #66cc66;">&#40;</span>expect <span style="color: #66cc66;">&#91;</span>awesome <span style="color: #66cc66;">&#40;</span>has<span style="color: #66cc66;">-</span>args <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>what<span style="color: #66cc66;">-</span>is<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>what-is calls awesome function internally.  We don&#8217;t care about what awesome function does, but we need to ensure that it does get called inside what-is with expected arguments passed to it.  The vector after has-args contains functions does exactly that.  Let&#8217;s say you accidentally deleted a parameter to awesome function call witin what-is:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn awesome <span style="color: #66cc66;">&#91;</span>a b c<span style="color: #66cc66;">&#93;</span> a<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>defn what<span style="color: #66cc66;">-</span>is <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>awesome <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>deftest should<span style="color: #66cc66;">-</span>be<span style="color: #66cc66;">-</span>awesome
  <span style="color: #66cc66;">&#40;</span>expect <span style="color: #66cc66;">&#91;</span>awesome <span style="color: #66cc66;">&#40;</span>has<span style="color: #66cc66;">-</span>args <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span>#<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>what<span style="color: #66cc66;">-</span>is<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>If you run the test above you should see the following result:</p>
<p>FAIL in (should-be-awesome) (NO_SOURCE_FILE:11)<br />
Unexpected number of arguments. Function name: awesome<br />
expected: 3<br />
actual: 2</p>
<p>The test failed because test-expect internally noticed the argument count is different, so it couldn&#8217;t verify all the arguments expected.  Let&#8217;s say you decided to refactor awesome function to take one less parameter, and you forgot to update all the calling locations.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn awesome <span style="color: #66cc66;">&#91;</span>a b<span style="color: #66cc66;">&#93;</span> a<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>defn what<span style="color: #66cc66;">-</span>is <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>awesome <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>deftest should<span style="color: #66cc66;">-</span>be<span style="color: #66cc66;">-</span>awesome
  <span style="color: #66cc66;">&#40;</span>expect <span style="color: #66cc66;">&#91;</span>awesome <span style="color: #66cc66;">&#40;</span>has<span style="color: #66cc66;">-</span>args <span style="color: #66cc66;">&#91;</span>#<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>what<span style="color: #66cc66;">-</span>is<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Ran 1 tests containing 0 assertions.<br />
0 failures, 0 errors</p>
<p>No matter how many times you run your test, nothing will fail.  test-expect only checks if the calling function (what-is) is calling the mocked function with same number of parameters.  It doesn&#8217;t actually check with the original awesome function to see how many arguments it is actually expecting.  This is very annoying because you might not know there is a problem until run-time.</p>
<p>It would be nice if test-expect verified that the REAL function has the correct number of parameters.  This is a fairly common problem in mock frameworks in dynamic languages.  Lucky this functionality is very simple to implement in Clojure.  Every function definition is attached with meta data such as function name, namespace, and expected arguments, etc&#8230;  For example:</p>
<p>user=&gt;; (meta (resolve &#8216;awesome))<br />
{:ns #&lt;;Namespace user&gt;;, :name awesome, :file &#8220;NO_SOURCE_PATH&#8221;, :line 7, :arglists ([a b])}</p>
<p>meta returns a map which contains arguments of the function via :arglists key.  You get the idea.</p>
<p>Originally I submitted a patch to Matt Clark which provided an implementation to fix the problem I described above.  Since then Matt has added this feature to test-expect with better error reporting than my original implementation.</p>
<p>Thanks Matt!</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=82</wfw:commentRss>
		</item>
		<item>
		<title>Yo rabbit, Trixx are for hackers</title>
		<link>http://leftrightfold.com/?p=81</link>
		<comments>http://leftrightfold.com/?p=81#comments</comments>
		<pubDate>Wed, 20 May 2009 01:14:32 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Clojure]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<category><![CDATA[RabbitMQ]]></category>

		<category><![CDATA[Trixx]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=81</guid>
		<description><![CDATA[I started a RabbitMQ administration and monitoring tool called Trixx on github.  It is written in Clojure, but it is still in the very early stages.  Hopefully the project will be rapidly developed in the next few weeks.  Currently, Trixx impements all the functionality that rabbitmqctl provides.  Since it is written in Clojure, it can [...]]]></description>
			<content:encoded><![CDATA[<p>I started a <a href="http://www.rabbitmq.com/">RabbitMQ</a> administration and monitoring tool called <a href="http://github.com/aaronfeng/trixx" target="_blank">Trixx</a> on github.  It is written in <a href="http://clojure.org/">Clojure</a>, but it is still in the very early stages.  Hopefully the project will be rapidly developed in the next few weeks.  Currently, Trixx impements all the functionality that rabbitmqctl provides.  Since it is written in Clojure, it can to be consumed from  your favorite JVM languages.  A wrapper will be written around the Clojure code, so that it can be consumed more idiomatically in other languages.  The eventual goal is to provide a fully functional administration and monitoring web interface for RabbitMQ.</p>
<p>More information can be found in the project <a href="http://github.com/aaronfeng/trixx" target="_blank">README</a> file on github.</p>
<p>project url:</p>
<p><a href="http://github.com/aaronfeng/trixx" target="_blank">http://github.com/aaronfeng/trixx</a></p>
<p>git clone url:</p>
<p><a href="git://github.com/aaronfeng/trixx.git" target="_blank">git://github.com/aaronfeng/trixx.git</a></p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=81</wfw:commentRss>
		</item>
		<item>
		<title>Philadelphia Functional Programming User Group Hack Night</title>
		<link>http://leftrightfold.com/?p=76</link>
		<comments>http://leftrightfold.com/?p=76#comments</comments>
		<pubDate>Mon, 18 May 2009 01:31:45 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Philly Lambda]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=76</guid>
		<description><![CDATA[Last Wednesday a few of us got together and hacked some Clojure, Scala, Erlang, and Perl at the Philly Lambda hack night.  I got a lot of positive feedback from the group, so we will do another one soon.  If you are interested in joining us in Center City, please sign up for the mailing [...]]]></description>
			<content:encoded><![CDATA[<p>Last Wednesday a few of us got together and hacked some Clojure, Scala, Erlang, and Perl at the <a href="http://groups.google.com/group/philly-lambda" target="_blank">Philly Lambda</a> hack night.  I got a lot of positive feedback from the group, so we will do another one soon.  If you are interested in joining us in Center City, please sign up for the mailing list.</p>
<p><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/05/philly-lambda-5-13-09-1.jpg"><br />
<img class="size-thumbnail wp-image-77 alignnone" title="philly-lambda-5-13-09-1" src="http://leftrightfold.com/wp-content/uploads/2009/05/philly-lambda-5-13-09-1-150x150.jpg" alt="philly-lambda-5-13-09-1" width="150" height="150" /></a></p>
<p><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/05/philly-lambda-5-13-09-2.jpg"><br />
<img class="size-thumbnail wp-image-77 alignnone" title="philly-lambda-5-13-09-2" src="http://leftrightfold.com/wp-content/uploads/2009/05/philly-lambda-5-13-09-2-150x150.jpg" alt="philly-lambda-5-13-09-2" width="150" height="150" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=76</wfw:commentRss>
		</item>
		<item>
		<title>How to build rabbit management console</title>
		<link>http://leftrightfold.com/?p=74</link>
		<comments>http://leftrightfold.com/?p=74#comments</comments>
		<pubDate>Sun, 26 Apr 2009 22:51:12 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[RabbitMQ]]></category>

		<category><![CDATA[AMQP]]></category>

		<category><![CDATA[Erlang]]></category>

		<category><![CDATA[JInterface]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=74</guid>
		<description><![CDATA[Using RabbitMQ (and other AMQP brokers) one can configure queues, exchanges and bindings during runtime via protocol.  The benefit of configuring via protocol is that the client does not have to rely on internal broker&#8217;s implementation.  As long as the client is capable of packing the packets and dropping them onto the network, it is [...]]]></description>
			<content:encoded><![CDATA[<p>Using <a href="http://www.rabbitmq.com/" target="_blank">RabbitMQ</a> (and other <a href="http://jira.amqp.org/confluence/display/AMQP/Advanced+Message+Queuing+Protocol" target="_blank">AMQP</a> brokers) one can configure queues, exchanges and bindings during runtime via protocol.  The benefit of configuring via protocol is that the client does not have to rely on internal broker&#8217;s implementation.  As long as the client is capable of packing the packets and dropping them onto the network, it is ready to play.  However, there is more information to be desired via protocol than just the construction of necessary moving parts that makes the client and broker happy.  Not to worry, the rabbitmqctl command line utility comes to the rescue.  It provides enough meta information to monitor and interact with the broker.  rabbitmqctl is shell script that delegates to rabbit_control.erl to communicate with various Erlang nodes in order to extract the information.</p>
<p>In the last few days I have been working on a web management console for RabbitMQ.  I basically need to emulate all the features provided by rabbitmqctl, but I don&#8217;t want to shell out to the command line.  So I have two choices: build the web console in Erlang or talk to Erlang nodes via <a href="http://erlang.org/doc/apps/jinterface/index.html" target="_blank">JInterface</a><sup>1</sup>.  I chose the latter.  JInterface ships with Erlang Otp, so if you already have RabbitMQ running you should be able to locate the OtpErlang.jar some where on your system.</p>
<p>To extract the information via JInterface is mostly painless, but tedious.  I&#8217;ll provide basic instructions here and maybe someone will find this information helpful.  I&#8217;ll assume the basics of Java programming are known.</p>
<p>The basic program structure looks like the following:</p>
<p>OtpSelf self = new OtpSelf(&#8221;monitor&#8221;, &#8220;YOUR-ERLANG-COOKIE-VALUE-HERE&#8221;);<br />
OtpPeer peer = new OtpPeer(&#8221;rabbit@server&#8221;);<br />
// Be sure to close the connection!<br />
OtpConnection conn = self.connect(peer);<br />
OtpErlangList arguments = new OtpErlangList();<br />
conn.sendRPC(module, function, arguments);<br />
OtpErlangObject result = conn.receiveRPC();</p>
<p>OtpSelf creates a node from Java that has the capability to interact with other Erlang nodes.  The first argument is the name of the node which can be called anything.  The second argument is the most important.  In order for Erlang nodes to communicate with each other, all the nodes must use the same magic cookie.  If the cookie value isn&#8217;t supplied properly, you will receive an OtpAuthException when trying to connect.  The RabbitMQ cookie file on my Macbook is located in /opt/local/var/lib/rabbitmq/.erlang.cookie.  Depending on your platform it might be stored in a different location.  I actually ran into a couple problems with the Erlang cookie file, but I&#8217;ll discuss it at the end of the article.</p>
<p>OtpPeer is the rabbit node you are connecting to.  Replace the &#8220;server&#8221; with the host name (hostname -s) of your machine that is running RabbitMQ.</p>
<p>In order for RabbitMQ to return any information, the correct function within a module must be invoked.  For example if you want to list all the virtual hosts in a broker:</p>
<p>conn.sendRPC(&#8221;rabbit_access_control&#8221;, &#8220;list_vhosts&#8221;, new OtpErlangList());</p>
<p>So how did I know it&#8217;s in module &#8220;rabbit_access_control&#8221; under a function with no arguments called &#8220;list_vhosts&#8221;?  Remember I said in the beginning that rabbitmqctl does this already?  If you look in rabbit_control.erl you can figure out pretty much anything you need to know.  Search for list_vhosts within the file and you will come across the following code:</p>
<p>action(list_vhosts, Node, [], Inform) -&gt;<br />
Inform(&#8221;Listing vhosts&#8221;, []),<br />
display_list(call(Node, {rabbit_access_control, list_vhosts, []}));</p>
<p>The second parameter of the call function is what one is after.  The first value of the tuple (surrounded by curly braces) is the module name followed by the function and arguments.  Going back to the list_vhosts example, let see what receivedRPC returns when requesting all the virtual hosts.  The easiest way is just output the toString on the OtpErlangObject.</p>
<p>System.out.println(result); -&gt; [#Bin&lt;1&gt;]</p>
<p>As one can see in this example the result is actually a collection of Erlang binary (#Bin) objects.  Since there&#8217;s only one virtual host on my broker, only one binary value is returned.  Let&#8217;s extract the value of the binary.  We&#8217;ll cheat since we know there are only one virtual host in this case.</p>
<p>OtpErlangBinary binary = (OtpErlangBinary)((OtpErlangList)result).elementAt(0);<br />
System.out.println(new String(binary.binaryValue()));</p>
<p>The code above is making a lot of assumptions.  I did this on purpose in order to focus on the important concepts, so don&#8217;t write the code like that in a production system.  Everything should be pretty self explanatory, maybe except for why I wrapped binaryValue with a new String.  binaryValue returns a byte array, passing it to a new String will convert it to human readable format.  Pretty easy right?</p>
<p>I have shown the simplest case, but for the more complicated return values all the concepts remain the same.  Remember I said it gets pretty tedious?  Most of the time it doesn&#8217;t just return a binary value in a collection, but it&#8217;s usually wrapped in a tuple.  It gets worse, sometimes tuples are wrapped in tuples and so on.  Like I said before, it&#8217;s not hard, just time consuming.</p>
<p>On my Macbook a ran into a couple issues with Erlang cookie file.  For whatever reason I had to copy the .erlang.cookie into my home directory.  I also had to map my hostname (hostname -s) to 127.0.0.1 in my /etc/hosts file.  Before attempting writing any monitoring code, make sure you can actually connect to the Erlang instance cleanly.  Once the connection is made, make sure you close the connection, otherwise you won&#8217;t be able to make subsequent connections without bouncing the server.</p>
<p>I have successfully emulated all the features of rabbitmqctl in Clojure.  I plan to throw JRuby on top of it for the frontend whenever I get a chance.</p>
<p>All these tedious parsing may go away after the management capability is a first class citizen in the AMQP protocol.  Until then, this is what you have to do if you want to monitor RabbitMQ.</p>
<p>If you get stuck, the <a href="http://erlang.org/doc/apps/jinterface/java/index.html" target="_blank">Java doc</a> for JInterface is pretty helpful.  I can illustrate a more complicated example in detail if someone finds this information helpful.  Please feel free to drop me a comment or email.</p>
<hr />1.  This is not entirely true.  I actually came across another option I didn&#8217;t know about when I wrote this post.  Apparently you can also use <a href="http://www.lysator.liu.se/~tab/erlang/py_interface/" target="_blank">Py-Interface</a> as express by Dmitriy Samovskiy on the<a href="http://www.nabble.com/emulating-rabbitmqctl-from-python-to23261300.html" target="_blank"> RabbitMQ mailing list</a> to accomplish the same thing.  The knowledge expressed here is general enough and still applies even if you use something else like Py-Interface.  If you know another way, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=74</wfw:commentRss>
		</item>
		<item>
		<title>schema_runner is on github</title>
		<link>http://leftrightfold.com/?p=73</link>
		<comments>http://leftrightfold.com/?p=73#comments</comments>
		<pubDate>Wed, 01 Apr 2009 02:20:32 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[F#]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<category><![CDATA[SchemaRunner]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=73</guid>
		<description><![CDATA[In the previous post I mentioned that I wanted to learn F# by rewriting a database utility that I oringinally implemented in C# for work.  I realized with all the projects I&#8217;m currently involved in, I don&#8217;t have the time to work on it.  I decided to make the repo publicly available on github for [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://leftrightfold.com/2009/02/10/fsharp-schemarunner/" target="_blank">previous</a> post I mentioned that I wanted to learn F# by rewriting a database utility that I oringinally implemented in C# for work.  I realized with all the projects I&#8217;m currently involved in, I don&#8217;t have the time to work on it.  I decided to make the <a href="http://github.com/aaronfeng/schema_runner/tree/master" target="_blank">repo publicly available on github</a> for anyone who wants to learn F#.  If you would like to take over the project, please drop me an email.</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=73</wfw:commentRss>
		</item>
		<item>
		<title>F# SchemaRunner</title>
		<link>http://leftrightfold.com/?p=68</link>
		<comments>http://leftrightfold.com/?p=68#comments</comments>
		<pubDate>Tue, 10 Feb 2009 05:01:18 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[F#]]></category>

		<category><![CDATA[SchemaRunner]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=68</guid>
		<description><![CDATA[A couple years ago I wrote a database utility for work that allowed us to update our development databases to a specific version.   The idea is simple.  We have a special database table to keep track of the last run script.  We call this special table SchemaInfo, and it contains exactly one [...]]]></description>
			<content:encoded><![CDATA[<p>A couple years ago I wrote a database utility for work that allowed us to update our development databases to a specific version.   The idea is simple.  We have a special database table to keep track of the last run script.  We call this special table SchemaInfo, and it contains exactly one column: VersionNumber.  Whenever the database needs to be updated we write a change script with the version number incremented by one from the previous script.  The only requirement is that the last statement of each change script needs to update the VersionNumber in SchemaInfo table.  The name of the change script starts with the version number to allow the scripts to be sorted sequentially.  This database versioning idea was originally borrowed from Rails 1.</p>
<p>I called this utility SchemaRunner.  It was originally written in C# to match our code base.</p>
<div id="attachment_58" class="wp-caption alignnone" style="width: 310px"><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/01/schema_runner.jpg"><img class="size-medium wp-image-58" title="ScheamRunner" src="http://leftrightfold.com/wp-content/uploads/2009/01/schema_runner-300x132.jpg" alt="Original C# version." width="300" height="132" /></a><p class="wp-caption-text">Click to enlarge.  Original C# version.</p></div>
<p>Earlier this year I decided to play around with <a href="http://en.wikipedia.org/wiki/F_Sharp_programming_language" target="_blank">F#</a>, so I figured the best way to learn it is to actually use it.  I&#8217;ll be rewriting SchemaRunner using F#.  I&#8217;ll be posting bits and pieces while I&#8217;m doing the rewrite.  When I&#8217;m finished I&#8217;ll make the source code freely available.  Maybe people will find the tool useful in their development environment.  Most important of all, this can serve as an example for anyone who wants to learn about F#.</p>
<p>Time to hack!</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=68</wfw:commentRss>
		</item>
		<item>
		<title>Philadelphia Hackathon</title>
		<link>http://leftrightfold.com/?p=70</link>
		<comments>http://leftrightfold.com/?p=70#comments</comments>
		<pubDate>Thu, 08 Jan 2009 04:40:15 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Hackathon]]></category>

		<category><![CDATA[Philly]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=70</guid>
		<description><![CDATA[We had a great turn out last night at the Hackathon.  It was good to meet people with that share a common interest.




]]></description>
			<content:encoded><![CDATA[<p>We had a great turn out last night at the <a href="http://www.groupomatic.com/haqsm3vj" target="_blank">Hackathon</a>.  It was good to meet people with that share a common interest.</p>
<p><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/01/hackathon1-2009-1-6.jpg"><br />
<img class="size-thumbnail wp-image-71 alignnone" title="hackathon1-2009-1-6" src="http://leftrightfold.com/wp-content/uploads/2009/01/hackathon1-2009-1-6-150x150.jpg" alt="hackathon1-2009-1-6" width="150" height="150" /></a></p>
<p><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/01/hackathon2-2009-1-6.jpg"><br />
</a><a rel="thumbnail" href="http://leftrightfold.com/wp-content/uploads/2009/01/hackathon2-2009-1-6.jpg"><img class="size-thumbnail wp-image-72 alignnone" title="hackathon2-2009-1-6" src="http://leftrightfold.com/wp-content/uploads/2009/01/hackathon2-2009-1-6-150x150.jpg" alt="hackathon2-2009-1-6" width="150" height="150" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=70</wfw:commentRss>
		</item>
		<item>
		<title>F# for 2009</title>
		<link>http://leftrightfold.com/?p=69</link>
		<comments>http://leftrightfold.com/?p=69#comments</comments>
		<pubDate>Sun, 04 Jan 2009 04:52:37 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[F#]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=69</guid>
		<description><![CDATA[In 2008 I studied Common Lisp, which I found very enjoyable and useful.  I do intend to continue my CL journey since I&#8217;m no where near the end.  Pragmatic Programmers suggests learning a new language every year, so it&#8217;s time for me to pickup something else.  I picked CL for 2008 because the s-expression syntax [...]]]></description>
			<content:encoded><![CDATA[<p>In 2008 I studied Common Lisp, which I found very enjoyable and useful.  I do intend to continue my CL journey since I&#8217;m no where near the end.  Pragmatic Programmers suggests learning a new language every year, so it&#8217;s time for me to pickup something else.  I picked CL for 2008 because the <a href="http://en.wikipedia.org/wiki/S-expression" target="_blank">s-expression</a> syntax was new to me (if you don&#8217;t count college), and Lisp contained many interesting concepts that I was not familiar with.  For 2009 I decided to use same strategy in picking my next language to learn.  After thinking about it, I decided to go with F#.</p>
<p><a href="http://en.wikipedia.org/wiki/Fsharp" target="_blank">What is F#?</a> I&#8217;ll let Wikipedia do the explaining:</p>
<blockquote><p><strong>F#</strong> (pronounced <strong>F Sharp</strong>) is a <a title="Multi-paradigm programming language" href="http://en.wikipedia.org/wiki/Multi-paradigm_programming_language" target="_blank">multi-paradigm programming language</a>, targeting the <a title=".NET Framework" href="http://en.wikipedia.org/wiki/.NET_Framework" target="_blank">.NET Framework</a>, that encompasses <a title="Functional programming" href="http://en.wikipedia.org/wiki/Functional_programming" target="_blank">functional programming</a> as well as <a title="Imperative programming" href="http://en.wikipedia.org/wiki/Imperative_programming">imperative</a> <a title="Object-oriented programming" href="http://en.wikipedia.org/wiki/Object-oriented_programming" target="_blank">object-oriented programming</a> disciplines. It is a variant of <a title="ML (programming language)" href="http://en.wikipedia.org/wiki/ML_%28programming_language%29" target="_blank">ML</a> and is largely compatible with the <a title="OCaml" href="http://en.wikipedia.org/wiki/OCaml" target="_blank">OCaml</a> implementation.</p></blockquote>
<p>Why did I pick F#?  In my day job, I work on a C# financial application that targets .NET Framework 3.5.  I hope that after learning F# I might be able to inject some functional goodness in our application since it will compile down to the same IL.  Even though F# is backed by Microsoft, it does run on multiple platforms via <a href="http://www.mono-project.com/Main_Page" target="_blank">Mono</a>, which is very important to me since I don&#8217;t use Windows at home.  F# is compatible with OCaml, I figure I&#8217;ll kill two birds with one stone.</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=69</wfw:commentRss>
		</item>
		<item>
		<title>Welcome</title>
		<link>http://leftrightfold.com/?p=40</link>
		<comments>http://leftrightfold.com/?p=40#comments</comments>
		<pubDate>Thu, 01 Jan 2009 04:34:55 +0000</pubDate>
		<dc:creator>Aaron Feng</dc:creator>
		
		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://leftrightfold.com/?p=40</guid>
		<description><![CDATA[As the name of the blog suggests, I&#8217;ll primarily focus on functional programming.  But from time to time I&#8217;ll discuss other topics such as compiler construction, metaprogramming, code generation, and domain specific languages since those are my favorite areas.
Like many people, I first encountered FP in my college days, and stayed far away from [...]]]></description>
			<content:encoded><![CDATA[<p>As the name of the blog suggests, I&#8217;ll primarily focus on functional programming.  But from time to time I&#8217;ll discuss other topics such as compiler construction, metaprogramming, code generation, and domain specific languages since those are my favorite areas.</p>
<p>Like many people, I first encountered FP in my college days, and stayed far away from it since then.  I re-discovered FP when I heard about Erlang a couple years ago.  Now I&#8217;m hooked.  Since Erlang, I have moved on to playing around with Lisp, Haskell, and F#.</p>
<p>Why functional programming?  I&#8217;m sure there are endless reasons why one should learn about functional programming.  At the end of the day, even if you never use any FP languages/techniques it will make you a better programmer.  The reason is simple: It will forever change the way you think and see the world.  You don&#8217;t have to take my word for it, you can read <a href="http://www.cs.chalmers.se/~rjmh/Papers/whyfp.pdf">Why Functional Programming Matters by John Hughes.</a></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://leftrightfold.com/?feed=rss2&amp;p=40</wfw:commentRss>
		</item>
	</channel>
</rss>
