Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
316 lines (250 sloc) 33.8 KB
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>9 You can’t be serious!?</title>
<link href="stylesheet.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="leanpub-main">
<h2 section-num="9" id="you-cant-be-serious"><span class="section-number">9 </span>You can&#x2019;t be serious!?</h2>
<p>In Practical Recursive Combinators, we enhanced <code>multirec</code> (a/k/a &#x201C;Divide and Conquer&#x201D;) and <code>linrec</code> (&#x201C;Linear Recursion&#x201D;) to accept as arguments any object that supports the <code>#to_proc</code> method. Today we&#x2019;re going demonstrate why: We will look at how removing the ceremony around lambdas makes using combinators like <code>multirec</code> more valuable for code we share with others.</p>
<p>Using <a href="http://github.com/raganwald/homoiconic/tree/master/2008-11-26/recursive_combinators.rb">recursive_combinators.rb</a> to define how to sum the squares of a nested list of numbers, we can write:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">require</code> <code class="s">'recursive_combinators'</code>
<code class="n">include</code> <code class="n">RecursiveCombinators</code>
<code class="n">multirec</code><code class="p">(</code>
<code class="n">lambda</code> <code class="p">{</code> <code class="o">|</code><code class="n">x</code><code class="o">|</code> <code class="n">x</code><code class="p">.</code><code class="n">kind_of</code>?<code class="p">(</code><code class="n">Numeric</code><code class="p">)</code> <code class="p">},</code>
<code class="n">lambda</code> <code class="p">{</code> <code class="o">|</code><code class="n">x</code><code class="o">|</code> <code class="n">x</code> <code class="o">**</code> 2 <code class="p">},</code>
<code class="n">lambda</code> <code class="p">{</code> <code class="o">|</code><code class="n">x</code><code class="o">|</code> <code class="n">x</code> <code class="p">},</code>
<code class="n">lambda</code> <code class="p">{</code> <code class="o">|</code><code class="n">x</code><code class="o">|</code> <code class="n">x</code><code class="p">.</code><code class="n">inject</code> <code class="p">{</code> <code class="o">|</code><code class="n">sum</code><code class="p">,</code> <code class="n">n</code><code class="o">|</code> <code class="n">sum</code> <code class="o">+</code> <code class="n">n</code> <code class="p">}</code> <code class="p">}</code>
<code class="p">)</code>
</pre></div>
</div>
<p>The trouble with this&#x2013;to quote <a href="http://www.amazon.com/gp/product/B000HA4WDY?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B000HA4WDY" title="Amazon.com: Dr. Seuss' How the Grinch Stole Christmas! (50th Birthday Deluxe Remastered Edition)">a seasonally appropriate character</a>&#x2013;is the noise, noise, Noise, NOISE! All those lambdas and parameter declarations outweigh the actual logic we are declaring, so much so that declaring this function using our abstraction is longer and may seem more obscure than declaring it without the abstraction.</p>
<p>This whole thing reminds me of languages where the keywords must be in UPPER CASE. Reading code in such languages is like listening to a poetry reading where the author shouts the punctuation:</p>
<blockquote>
<p>Two roads diverged in a yellow wood COMMA!<br />
And sorry I could not travel both<br />
And be one traveler COMMA! long I stood<br />
And looked down one as far as I could<br />
To where it bent in the undergrowth SEMI-COMMA!!</p>
</blockquote>
<p>Finding ways to abbreviate our declaration is more than just a little &#x201C;syntactic sugar:&#x201D; It&#x2019;s a way of emphasizing what is important, our algorithms, and de-emphasizing what is not important, the scaffolding and ceremony of instantiating <code>Proc</code> objects in Ruby. One of those ways is to use <a href="http:string_to_proc.rb"><code>String#to_proc</code></a>.</p>
<h3 section-num="9.1" id="string-to-proc"><span class="section-number">9.1 </span>String to Proc</h3>
<p><code>String#to_proc</code> adds the <code>#to_proc</code> method to the <code>String</code> class in Ruby. This allows you to write certain simple lambdas as strings instead of using the <code>lambda</code> keyword, the <code>proc</code> keyword, or <code>Proc.new</code>. The reason why you&#x2019;d bother is that <code>String#to_proc</code> provides some shortcuts that get rid of the noise.</p>
<p>
<strong>gives</strong>
</p>
<p><code>String#to_proc</code> provides several key abbreviations: First, <code>-&gt;</code> syntax for lambdas in Ruby 1.8. So instead of <code>lambda { |x,y| x + y }</code>, you can write <code>'x,y -&gt; x + y'</code>. I read this out loud as &#x201C;<em>x and y gives x plus y</em>.&#x201D; </p>
<p>This syntax gets rid of the noisy <code>lambda</code> keyword and is much closer to Ruby 1.9 syntax. And frankly, reading it out loud makes much more sense than reading lambdas aloud. Our example above could be written:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">require</code> <code class="s">'string_to_proc'</code>
<code class="n">multirec</code><code class="p">(</code>
<code class="s">'x -&gt; x.kind_of?(Numeric)'</code><code class="p">,</code>
<code class="s">'x -&gt; x ** 2'</code><code class="p">,</code>
<code class="s">'x -&gt; x'</code><code class="p">,</code>
<code class="s">'x -&gt; x.inject { |sum, n| sum + n }'</code>
<code class="p">)</code>
</pre></div>
</div>
<p>This is a lot better than the version with lambdas, and if the <code>-&gt;</code> seems foreign, it is only because <code>-&gt;</code> is in keeping with modern functional languages and mathematical notation, while <code>lambda</code> is in keeping with Lisp and lambda calculus notation without the ability to use a single lambda character unicode.</p>
<p>
<strong>inferred parameters</strong>
</p>
<p>Second, <code>String#to_proc</code> adds inferred parameters: If you do not use <code>-&gt;</code>, <code>String#to_proc</code> attempts to infer the parameters. So if you write <code>'x + y'</code>, <code>String#to_proc</code> treats it as <code>x,y -&gt; x + y</code>. There are certain expressions where this doesn&#x2019;t work, and you have to use <code>-&gt;</code>, but for really simple cases it works just fine. And frankly, for really simple cases you don&#x2019;t need the extra scaffolding. Here&#x2019;s our example with the first three lambdas using inferred parameters:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">multirec</code><code class="p">(</code>
<code class="s">'x.kind_of?(Numeric)'</code><code class="p">,</code>
<code class="s">'x ** 2'</code><code class="p">,</code>
<code class="s">'x'</code><code class="p">,</code>
<code class="s">'z -&gt; z.inject { |sum, n| sum + n }'</code>
<code class="p">)</code>
</pre></div>
</div>
<blockquote>
<p>I have good news and bad news about inferred parameters and <code>String#to_proc</code> in general. It uses regular expressions to do its thing, which means that complicated things often don&#x2019;t work. For example, nesting <code>-&gt;</code> only works when writing functions that return functions. So <code>'x -&gt; y -&gt; x + y'</code> is a function that takes an <code>x</code> and returns a function that takes a <code>y</code> and returns <code>x + y</code>. That works. But <code>'z -&gt; z.inject(&amp;"sum, n -&gt; sum + n")'</code> does NOT work.</p>
</blockquote>
<blockquote>
<p>I considered fixing this with more sophisticated parsing, however the simple truth is this: <code>String#to_proc</code> is not a replacement for <code>lambda</code>, it&#x2019;s a tool to be used when what you&#x2019;re doing is so simple that <code>lambda</code> is overkill. If <code>String#to_proc</code> doesn&#x2019;t work for something, it probably isn&#x2019;t ridiculously simple any more.</p>
</blockquote>
<p>
<strong>it</strong>
</p>
<p>The third abbreviation is a special case. If there is only one parameter, you can use <code>_</code> (the underscore) without naming it. This is often called the &#x201C;hole&#x201D; or pronounced &#x201C;it.&#x201D; If you use &#x201C;it,&#x201D; then <code>String#to_proc</code> doesn&#x2019;t try to infer any more parameters, so this can help you write things like:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">multirec</code><code class="p">(</code>
<code class="s">'_.kind_of?(Numeric)'</code><code class="p">,</code>
<code class="s">'_ ** 2'</code><code class="p">,</code>
<code class="s">'_'</code><code class="p">,</code>
<code class="s">'_.inject { |sum, n| sum + n }'</code>
<code class="p">)</code>
</pre></div>
</div>
<p>Admittedly, use of &#x201C;it&#x201D;/the hole is very much a matter of taste.</p>
<p>
<strong>point-free</strong>
</p>
<p><code>String#to_proc</code> has a fourth and even more extreme abbreviation up its sleeve, <a href="http://blog.plover.com/prog/haskell/" title="The Universe of Discourse : Note on point-free programming style">point-free style</a>: &#x201C;Function points&#x201D; are what functional programmers usually call parameters. Point-free style consists of describing how functions are composed together rather than describing what happens with their arguments. So, let&#x2019;s say that I want a function that combines <code>.inject</code> with <code>+</code>. One way to say that is to say that I want a new function that takes its argument and applies an <code>inject</code> to it, and the inject takes another function with two arguments and applies a <code>+</code> to them:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">lambda</code> <code class="p">{</code> <code class="o">|</code><code class="n">z</code><code class="o">|</code> <code class="n">z</code><code class="p">.</code><code class="n">inject</code> <code class="p">{</code> <code class="o">|</code><code class="n">sum</code><code class="p">,</code> <code class="n">n</code><code class="o">|</code> <code class="n">sum</code> <code class="o">+</code> <code class="n">n</code> <code class="p">}</code> <code class="p">}</code>
</pre></div>
</div>
<p>The other way is to say that I want to compose <code>.inject</code> and <code>+</code> together. Without getting into a <code>compose</code> function like Haskell&#x2019;s <code>.</code> operator, <code>String#to_proc</code> has enough magic to let us write the above as:</p>
<div class="code-block">
<div class="highlight"><pre>"<code class="p">.</code><code class="n">inject</code><code class="p">(</code><code class="o">&amp;</code><code class="s">'+'</code><code class="p">)</code>"
</pre></div>
</div>
<p>Meaning &#x201C;<em>I want a new lambda that does an inject using plus</em>.&#x201D; Point-free style does require a new way of thinking about some things, but it is a clear win for simple cases. Proof positive of this is the fact that Ruby on Rails and Ruby 1.9 have both embraced point-free style with <code>Symbol#to_proc</code>. That&#x2019;s exactly how <a href="http://weblog.raganwald.com/2008/02/1100inject.html" title="(1..100).inject(&amp;:+)"><code>(1..100).inject(&amp;:+)</code></a> works!</p>
<p><code>String#to_proc</code> supports fairly simple cases where you are sending a message or using a binary operator. So if we wanted to go all out, we could write our example as:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">multirec</code><code class="p">(</code><code class="s">'.kind_of?(Numeric)'</code><code class="p">,</code> <code class="s">'** 2'</code><code class="p">,</code> <code class="s">'x'</code><code class="p">,</code> "<code class="p">.</code><code class="n">inject</code><code class="p">(</code><code class="o">&amp;</code><code class="s">'+'</code><code class="p">)</code>"<code class="p">)</code>
</pre></div>
</div>
<blockquote>
<p>There&#x2019;s no point-free magic for the identity function, although this example tempts me to special case the empty string!</p>
</blockquote>
<p>
<strong>When should we use all these tricks?</strong>
</p>
<p><code>String#to_proc</code> provides these options so that you as a programmer can choose your level of ceremony around writing functions. But of course, you have to use the tool wisely. My <em>personal</em> rules of thumb are:</p>
<ol><li>Embrace inferred parameters for well-known mathematical or logical operations. For these operations, descriptive parameter names are usually superfluous. Follow the well-known standard and use <code>x</code>, <code>y</code>, <code>z</code>, and <code>w</code>; or <code>a</code>, <code>b</code> and <code>c</code>; or <code>n</code>, <code>i</code>, <code>j</code>, and <code>k</code> for the parameters. If whatever it is makes no sense using those variable names, don&#x2019;t used inferred parameters.</li>
<li>Embrace the hole for extremely simple one-parameter lambdas that aren&#x2019;t intrinsically mathematical or logical such as methods that use <code>.method_name</code> and for the identity function.</li>
<li>Embrace point-free style for methods that look like operators.</li>
<li>Embrace <code>-&gt;</code> notation for extremely simple cases where I want to give the parameters a descriptive name.</li>
<li>Use lambdas for everything else.</li>
</ol><p>So I would write:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">multirec</code><code class="p">(</code> <code class="s">'_.kind_of?(Numeric)'</code><code class="p">,</code> <code class="s">'** 2'</code><code class="p">,</code> <code class="s">'_'</code><code class="p">,</code> "<code class="n">_</code><code class="p">.</code><code class="n">inject</code><code class="p">(</code><code class="o">&amp;</code><code class="s">'+'</code><code class="p">)</code>"<code class="p">)</code>
</pre></div>
</div>
<p>I read the parameters out loud as:</p>
<ul><li><em>it kind_of? Numeric;</em></li>
<li><em>raise to the power of two;</em></li>
<li><em>it;</em></li>
<li><em>it inject plus</em>.</li>
</ul><p>And yes, I consider <code>multirec( '_.kind_of?(Numeric)', '** 2', '_', "_.inject(&amp;'+')")</code> more succinct and easier to read than: </p>
<div class="code-block">
<div class="highlight"><pre><code class="n">def</code> <code class="n">sum_squares</code><code class="p">(</code><code class="n">value</code><code class="p">)</code>
<code class="k">if</code> <code class="n">value</code><code class="p">.</code><code class="n">kind_of</code>?<code class="p">(</code><code class="n">Numeric</code><code class="p">)</code>
<code class="n">value</code> <code class="o">**</code> 2
<code class="k">else</code>
<code class="n">value</code><code class="p">.</code><code class="n">map</code> <code class="n">do</code> <code class="o">|</code><code class="n">sub_value</code><code class="o">|</code>
<code class="n">sum_squares</code><code class="p">(</code><code class="n">sub_value</code><code class="p">)</code>
<code class="k">end</code><code class="p">.</code><code class="n">inject</code> <code class="p">{</code> <code class="o">|</code><code class="n">x</code><code class="p">,</code><code class="n">y</code><code class="o">|</code> <code class="n">x</code> <code class="o">+</code> <code class="n">y</code> <code class="p">}</code>
<code class="k">end</code>
<code class="k">end</code>
</pre></div>
</div>
<p>If all this is new too you, <code>String#to_proc</code> may seem like gibberish and <code>def sum_squares</code> may seem reassuringly sensible. But try to remember that combinators like <code>multirec</code> are built to disentangle the question of what we are doing from how we are doing it. This is the third straight post about recursive combinators using one of three different examples. So of course we know what <code>sum_squares</code> does and how it does it.</p>
<p>But try to imagine you are looking at a piece of code that isn&#x2019;t so simple, that isn&#x2019;t so obvious. Maybe it was written by someone else, maybe you wrote it a while ago. If you see:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">def</code> <code class="n">rotate</code><code class="p">(</code><code class="n">square</code><code class="p">)</code>
<code class="k">return</code> <code class="n">square</code> <code class="n">unless</code> <code class="n">square</code><code class="p">.</code><code class="n">kind_of</code>?<code class="p">(</code><code class="n">Enumerable</code><code class="p">)</code> <code class="o">&amp;&amp;</code> <code class="n">square</code><code class="p">.</code><code class="nb">size</code> <code class="o">&gt;</code> 1
<code class="n">half_sz</code> <code class="p">=</code> <code class="n">square</code><code class="p">.</code><code class="nb">size</code> <code class="o">/</code> 2
<code class="n">sub_square</code> <code class="p">=</code> <code class="n">lambda</code> <code class="n">do</code> <code class="o">|</code><code class="n">row</code><code class="p">,</code> <code class="n">col</code><code class="o">|</code>
<code class="n">square</code><code class="p">.</code><code class="n">slice</code><code class="p">(</code><code class="n">row</code><code class="p">,</code> <code class="n">half_sz</code><code class="p">).</code><code class="n">map</code> <code class="p">{</code> <code class="o">|</code><code class="n">a_row</code><code class="o">|</code> <code class="n">a_row</code><code class="p">.</code><code class="n">slice</code><code class="p">(</code><code class="n">col</code><code class="p">,</code> <code class="n">half_sz</code><code class="p">)</code> <code class="p">}</code>
<code class="k">end</code>
<code class="n">upper_left</code> <code class="p">=</code> <code class="n">rotate</code><code class="p">(</code><code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code>0<code class="p">,</code>0<code class="p">))</code>
<code class="n">lower_left</code> <code class="p">=</code> <code class="n">rotate</code><code class="p">(</code><code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code><code class="n">half_sz</code><code class="p">,</code>0<code class="p">))</code>
<code class="n">upper_right</code> <code class="p">=</code> <code class="n">rotate</code><code class="p">(</code><code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code>0<code class="p">,</code><code class="n">half_sz</code><code class="p">))</code>
<code class="n">lower_right</code> <code class="p">=</code> <code class="n">rotate</code><code class="p">(</code><code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code><code class="n">half_sz</code><code class="p">,</code><code class="n">half_sz</code><code class="p">))</code>
<code class="n">upper_right</code><code class="p">.</code><code class="n">zip</code><code class="p">(</code><code class="n">lower_right</code><code class="p">).</code><code class="n">map</code> <code class="p">{</code> <code class="o">|</code><code class="n">l</code><code class="p">,</code><code class="n">r</code><code class="o">|</code> <code class="n">l</code> <code class="o">+</code> <code class="n">r</code> <code class="p">}</code> <code class="o">+</code>
<code class="n">upper_left</code><code class="p">.</code><code class="n">zip</code><code class="p">(</code><code class="n">lower_left</code><code class="p">).</code><code class="n">map</code> <code class="p">{</code> <code class="o">|</code><code class="n">l</code><code class="p">,</code><code class="n">r</code><code class="o">|</code> <code class="n">l</code> <code class="o">+</code> <code class="n">r</code> <code class="p">}</code>
<code class="k">end</code>
</pre></div>
</div>
<p>Do you see at once how it works? Do you see at a glance whether the recursive strategy was implemented properly? Can you tell whether there&#x2019;s something buggy about it? For example, this code only works rotating square matrices that have sides which are powers of two. What needs to be changed to fix that? Are you sure you can fix it without breaking the divide and conquer strategy?</p>
<p>For a method like this, I would write:</p>
<div class="code-block">
<div class="highlight"><pre><code class="n">multirec</code><code class="p">(</code>
<code class="p">:</code><code class="n">cond</code> <code class="p">=</code><code class="o">&gt;</code> "!<code class="p">(</code><code class="n">_</code><code class="p">.</code><code class="n">kind_of</code>?<code class="p">(</code><code class="n">Enumerable</code><code class="p">)</code> <code class="o">&amp;&amp;</code> <code class="n">_</code><code class="p">.</code><code class="nb">size</code> <code class="o">&gt;</code> 1<code class="p">)</code>"<code class="p">,</code>
<code class="p">:</code><code class="n">then</code> <code class="p">=</code><code class="o">&gt;</code> "<code class="n">_</code>"<code class="p">,</code>
<code class="p">:</code><code class="n">before</code> <code class="p">=</code><code class="o">&gt;</code> <code class="n">lambda</code> <code class="n">do</code> <code class="o">|</code><code class="n">square</code><code class="o">|</code>
<code class="n">half_sz</code> <code class="p">=</code> <code class="n">square</code><code class="p">.</code><code class="nb">size</code> <code class="o">/</code> 2
<code class="n">sub_square</code> <code class="p">=</code> <code class="n">lambda</code> <code class="n">do</code> <code class="o">|</code><code class="n">row</code><code class="p">,</code> <code class="n">col</code><code class="o">|</code>
<code class="n">square</code><code class="p">.</code><code class="n">slice</code><code class="p">(</code><code class="n">row</code><code class="p">,</code> <code class="n">half_sz</code><code class="p">).</code><code class="n">map</code> <code class="p">{</code> <code class="o">|</code><code class="n">a_row</code><code class="o">|</code> <code class="n">a_row</code><code class="p">.</code><code class="n">slice</code><code class="p">(</code><code class="n">col</code><code class="p">,</code> <code class="n">half_sz</code><code class="p">)</code> <code class="p">}</code>
<code class="k">end</code>
<code class="n">upper_left</code> <code class="p">=</code> <code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code>0<code class="p">,</code>0<code class="p">)</code>
<code class="n">lower_left</code> <code class="p">=</code> <code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code><code class="n">half_sz</code><code class="p">,</code>0<code class="p">)</code>
<code class="n">upper_right</code> <code class="p">=</code> <code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code>0<code class="p">,</code><code class="n">half_sz</code><code class="p">)</code>
<code class="n">lower_right</code> <code class="p">=</code> <code class="n">sub_square</code><code class="p">.</code><code class="n">call</code><code class="p">(</code><code class="n">half_sz</code><code class="p">,</code><code class="n">half_sz</code><code class="p">)</code>
<code class="p">[</code><code class="n">upper_left</code><code class="p">,</code> <code class="n">lower_left</code><code class="p">,</code> <code class="n">upper_right</code><code class="p">,</code> <code class="n">lower_right</code><code class="p">]</code>
<code class="k">end</code><code class="p">,</code>
<code class="p">:</code><code class="n">after</code> <code class="p">=</code><code class="o">&gt;</code> <code class="n">lambda</code> <code class="n">do</code> <code class="o">|</code><code class="n">list</code><code class="o">|</code>
<code class="n">upper_left</code><code class="p">,</code> <code class="n">lower_left</code><code class="p">,</code> <code class="n">upper_right</code><code class="p">,</code> <code class="n">lower_right</code> <code class="p">=</code> <code class="n">list</code>
<code class="n">upper_right</code><code class="p">.</code><code class="n">zip</code><code class="p">(</code><code class="n">lower_right</code><code class="p">).</code><code class="n">map</code><code class="p">(</code><code class="o">&amp;</code><code class="s">'+'</code><code class="p">)</code> <code class="o">+</code> <code class="n">upper_left</code><code class="p">.</code><code class="n">zip</code><code class="p">(</code><code class="n">lower_left</code><code class="p">).</code><code class="n">map</code><code class="p">(</code><code class="o">\</code>
<code class="o">&amp;</code><code class="s">'+'</code><code class="p">)</code>
<code class="k">end</code>
<code class="k">end</code>
</pre></div>
</div>
<p>And be assured that months from now if I wanted to support rotating rectangular matrices of arbitrary size, I could modify <code>:cond</code>, <code>:before</code>, and <code>:after</code> with confidence that the basic method was not being broken.</p>
<h3 section-num="9.2" id="the-message"><span class="section-number">9.2 </span>The Message</h3>
<p>The message here is that taken by themselves, tools like recursive combinators or <code>String#to_proc</code> just look strange. But when we use them together, they reinforce each other and the sum becomes much greater than the sum of the parts. In the case of <code>String#to_proc</code>, it looks like frivolity to most Ruby programmers, because they don&#x2019;t use that many lambdas: Why should they when the existing syntax makes writing combinators hard to use? But when we have combinators in our hand, we see how <code>String#to_proc</code> can make them a win. So two things that look weird on their own are a useful tool when used in conjunction.</p>
<p>Our final example ended up being slightly longer than a naive version, however it is longer in ways that matter rather than longer in a mindless ceremonial way like some languages.</p>
<p>And that&#x2019;s the point of languages like Ruby: <strong>You</strong> have the tools to decide which portions of you code matter more than others, and to make the parts that matter stand out and the parts that don&#x2019;t go away. You may disagree with my choice of what matters for a recursive divide and conquer algorithm, but I hope we can agree that it&#x2019;s valuable to be able to make that choice for yourself or your team.</p>
<p>Seriously.</p>
</div>
<div id="leanpub-toc">
<h2>Table of Contents</h2>
<ol class="toc">
<li class="section"><a href="chap00.html#the-mit-license"><span class="section-number">0.1 </span>The MIT License</a></li>
<li class="section"><a href="chap00.html#preface"><span class="section-number">0.2 </span>Preface</a></li>
<li class="chapter"><a href="chap01.html#introduction"><span class="section-number">1 </span>Introduction</a></li>
<li class="chapter"><a href="chap02.html#kestrels"><span class="section-number">2 </span>Kestrels</a></li>
<li class="section"><a href="chap02.html#object-initializer-blocks"><span class="section-number">2.1 </span>Object initializer blocks</a></li>
<li class="section"><a href="chap02.html#inside-an-idiomatic-ruby-kestrel"><span class="section-number">2.2 </span>Inside, an idiomatic Ruby Kestrel</a></li>
<li class="section"><a href="chap02.html#the-enchaining-kestrel"><span class="section-number">2.3 </span>The Enchaining Kestrel</a></li>
<li class="section"><a href="chap02.html#the-obdurate-kestrel"><span class="section-number">2.4 </span>The Obdurate Kestrel</a></li>
<li class="section"><a href="chap02.html#kestrels-on-rails"><span class="section-number">2.5 </span>Kestrels on Rails</a></li>
<li class="section"><a href="chap02.html#rewriting-returning-in-rails"><span class="section-number">2.6 </span>Rewriting &#x201C;Returning&#x201D; in Rails</a></li>
<li class="chapter"><a href="chap03.html#the-thrush"><span class="section-number">3 </span>The Thrush</a></li>
<li class="section"><a href="chap03.html#let"><span class="section-number">3.1 </span>Let</a></li>
<li class="chapter"><a href="chap04.html#songs-of-the-cardinal"><span class="section-number">4 </span>Songs of the Cardinal</a></li>
<li class="section"><a href="chap04.html#building-a-cardinal-in-ruby"><span class="section-number">4.1 </span>Building a Cardinal in Ruby</a></li>
<li class="chapter"><a href="chap05.html#quirky-birds-and-meta-syntactic-programming"><span class="section-number">5 </span>Quirky Birds and Meta-Syntactic Programming</a></li>
<li class="section"><a href="chap05.html#a-limited-interpretation-of-the-quirky-bird-in-ruby"><span class="section-number">5.1 </span>A limited interpretation of the Quirky Bird in Ruby</a></li>
<li class="section"><a href="chap05.html#embracing-the-quirky-bird"><span class="section-number">5.2 </span>Embracing the Quirky Bird</a></li>
<li class="section"><a href="chap05.html#andand-even-more"><span class="section-number">5.3 </span>Andand even more</a></li>
<li class="chapter"><a href="chap06.html#aspect-oriented-programming-in-ruby-using-combinator-birds"><span class="section-number">6 </span>Aspect-Oriented Programming in Ruby using Combinator Birds</a></li>
<li class="section"><a href="chap06.html#giving-methods-advice"><span class="section-number">6.1 </span>Giving methods advice</a></li>
<li class="section"><a href="chap06.html#the-super-keyword-perhaps-youve-heard-of-it"><span class="section-number">6.2 </span>The super keyword, perhaps you&#x2019;ve heard of it?</a></li>
<li class="section"><a href="chap06.html#the-queer-bird"><span class="section-number">6.3 </span>The Queer Bird</a></li>
<li class="chapter"><a href="chap07.html#mockingbirds"><span class="section-number">7 </span>Mockingbirds</a></li>
<li class="section"><a href="chap07.html#duplicative-combinators"><span class="section-number">7.1 </span>Duplicative Combinators</a></li>
<li class="section"><a href="chap07.html#recursive-lambdas-in-ruby"><span class="section-number">7.2 </span>Recursive Lambdas in Ruby</a></li>
<li class="section"><a href="chap07.html#recursive-combinatorics"><span class="section-number">7.3 </span>Recursive Combinatorics</a></li>
<li class="section"><a href="chap07.html#recursive-combinators-in-idiomatic-ruby"><span class="section-number">7.4 </span>Recursive Combinators in Idiomatic Ruby</a></li>
<li class="section"><a href="chap07.html#the-mockingbird"><span class="section-number">7.5 </span>The Mockingbird</a></li>
<li class="chapter"><a href="chap08.html#refactoring-methods-with-recursive-combinators"><span class="section-number">8 </span>Refactoring Methods with Recursive Combinators</a></li>
<li class="section"><a href="chap08.html#divide-and-conquer"><span class="section-number">8.1 </span>Divide and Conquer</a></li>
<li class="section"><a href="chap08.html#the-merge-sort"><span class="section-number">8.2 </span>The Merge Sort</a></li>
<li class="section"><a href="chap08.html#separating-declaration-from-implementation"><span class="section-number">8.3 </span>Separating Declaration from Implementation</a></li>
<li class="section"><a href="chap08.html#practical-recursive-combinators"><span class="section-number">8.4 </span>Practical Recursive Combinators</a></li>
<li class="section"><a href="chap08.html#spicing-things-up"><span class="section-number">8.5 </span>Spicing things up</a></li>
<li class="section"><a href="chap08.html#building-on-a-legacy"><span class="section-number">8.6 </span>Building on a legacy</a></li>
<li class="section"><a href="chap08.html#seriously"><span class="section-number">8.7 </span>Seriously</a></li>
<li class="section"><a href="chap08.html#separating-implementation-from-declaration"><span class="section-number">8.8 </span>Separating Implementation from Declaration</a></li>
<li class="section"><a href="chap08.html#a-really-simple-recursive-combinator"><span class="section-number">8.9 </span>A Really Simple Recursive Combinator</a></li>
<li class="chapter"><a href="chap09.html#you-cant-be-serious"><span class="section-number">9 </span>You can&#x2019;t be serious!?</a></li>
<li class="section"><a href="chap09.html#string-to-proc"><span class="section-number">9.1 </span>String to Proc</a></li>
<li class="section"><a href="chap09.html#the-message"><span class="section-number">9.2 </span>The Message</a></li>
<li class="chapter"><a href="chap10.html#the-hopelessly-egocentric-book-chapter"><span class="section-number">10 </span>The Hopelessly Egocentric Book Chapter</a></li>
<li class="section"><a href="chap10.html#object-oriented-egocentricity"><span class="section-number">10.1 </span>Object-oriented egocentricity</a></li>
<li class="chapter"><a href="chap11.html#bonus-chapter-separating-concerns-in-coffeescript-using-aspect-oriented-programming"><span class="section-number">11 </span>Bonus Chapter: Separating Concerns in Coffeescript using Aspect-Oriented Programming</a></li>
<li class="chapter"><a href="chap12.html#appendix-finding-joy-in-combinators"><span class="section-number">12 </span>Appendix: Finding Joy in Combinators</a></li>
<li class="section"><a href="chap12.html#languages-for-combinatorial-logic"><span class="section-number">12.1 </span>Languages for combinatorial logic</a></li>
<li class="section"><a href="chap12.html#concatenative-languages"><span class="section-number">12.2 </span>Concatenative languages</a></li>
<li class="chapter"><a href="chap13.html#appendix-source-code"><span class="section-number">13 </span>Appendix: Source Code</a></li>
<li class="section"><a href="chap13.html#kestrels-1"><span class="section-number">13.1 </span>kestrels</a></li>
<li class="section"><a href="chap13.html#thrushes"><span class="section-number">13.2 </span>thrushes</a></li>
<li class="section"><a href="chap13.html#the-cardinal"><span class="section-number">13.3 </span>the cardinal</a></li>
<li class="section"><a href="chap13.html#quirky-birds"><span class="section-number">13.4 </span>quirky birds</a></li>
<li class="section"><a href="chap13.html#bluebirds"><span class="section-number">13.5 </span>bluebirds</a></li>
<li class="chapter"><a href="chap14.html#about-the-author"><span class="section-number">14 </span>About The Author</a></li>
<li class="section"><a href="chap14.html#contact"><span class="section-number">14.1 </span>contact</a></li>
</ol>
</div>
</body>
</html>