<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Gray Soft / Higher-Order Ruby / Currying</title>
  <id>tag:graysoftinc.com,2014-03-20:/posts/10</id>
  <updated>2014-03-28T20:35:34Z</updated>
  <link rel="self" href="http://graysoftinc.com/higher-order-ruby/currying/feed.xml"/>
  <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying"/>
  <author>
    <name>James Edward Gray II</name>
  </author>
  <entry>
    <title>The 4th Comment on "Currying"</title>
    <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying#comment_135"/>
    <id>tag:graysoftinc.com,2007-10-06:/comments/135</id>
    <updated>2014-03-28T20:35:34Z</updated>
    <summary>He only used square brackets as a shortcut (i.e. `Proc#[]` is an alias to `Proc#call`).

You can replace the square brackets `[...]` in his example with `.call(...)` and things will work just the same.</summary>
    <content type="html">&lt;p&gt;He only used square brackets as a shortcut (i.e. &lt;code&gt;Proc#[]&lt;/code&gt; is an alias to &lt;code&gt;Proc#call&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;You can replace the square brackets &lt;code&gt;[...]&lt;/code&gt; in his example with &lt;code&gt;.call(...)&lt;/code&gt; and things will work just the same.&lt;/p&gt;</content>
    <author>
      <name>Suraj</name>
    </author>
  </entry>
  <entry>
    <title>The 3rd Comment on "Currying"</title>
    <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying#comment_81"/>
    <id>tag:graysoftinc.com,2006-11-23:/comments/81</id>
    <updated>2014-03-28T20:34:49Z</updated>
    <summary>In Python:

```python
&amp;gt;&amp;gt;&amp;gt; import functools
&amp;gt;&amp;gt;&amp;gt; five_or_higher = functools.partial(max, 5)
&amp;gt;&amp;gt;&amp;gt; five_or_higher(6)
6
&amp;gt;&amp;gt;&amp;gt; five_or_higher(3)
5
```

According to the Python docs, partial could be implemented like this:

```python
def parti...</summary>
    <content type="html">&lt;p&gt;In Python:&lt;/p&gt;

&lt;div class="highlight highlight-python"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;functools&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;five_or_higher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;functools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;five_or_higher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;five_or_higher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;According to the Python docs, partial could be implemented like this:&lt;/p&gt;

&lt;div class="highlight highlight-python"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;newfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;fkeywords&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;newkeywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;newkeywords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fkeywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fargs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;newkeywords&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;newfunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;
    &lt;span class="n"&gt;newfunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
    &lt;span class="n"&gt;newfunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keywords&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;newfunc&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that this partial function supports both positional and keyword arguments. &lt;/p&gt;

&lt;p&gt;Another interesting version looks like this:&lt;/p&gt;

&lt;div class="highlight highlight-python"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;partial&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;addWorld&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" world!"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;addWorld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello,"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;"Hello, world"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.xoltar.org/2003/jun/25/partialModule.html"&gt;http://www.xoltar.org/2003/jun/25/partialModule.html&lt;/a&gt;&lt;/p&gt;</content>
    <author>
      <name>Paul</name>
    </author>
  </entry>
  <entry>
    <title>The 2nd Comment on "Currying"</title>
    <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying#comment_80"/>
    <id>tag:graysoftinc.com,2006-11-23:/comments/80</id>
    <updated>2014-03-28T20:35:34Z</updated>
    <summary>What I find strange is that the syntax for calling your curried function uses square brackets whereas the syntax for calling regular methods (like `puts` and `chop`) uses parens. It&amp;#39;s an unfortunate aspect of Ruby&amp;#39;s design. Python can do most of t...</summary>
    <content type="html">&lt;p&gt;What I find strange is that the syntax for calling your curried function uses square brackets whereas the syntax for calling regular methods (like &lt;code&gt;puts&lt;/code&gt; and &lt;code&gt;chop&lt;/code&gt;) uses parens. It's an unfortunate aspect of Ruby's design. Python can do most of the same tricks but both the input and the output of the curry are Python "callables" called with parens.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.python.org/dev/peps/pep-0309/"&gt;http://www.python.org/dev/peps/pep-0309/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549"&gt;http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549&lt;/a&gt;&lt;/p&gt;</content>
    <author>
      <name>Paul</name>
    </author>
  </entry>
  <entry>
    <title>The 1st Comment on "Currying"</title>
    <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying#comment_79"/>
    <id>tag:graysoftinc.com,2006-11-22:/comments/79</id>
    <updated>2014-03-28T21:20:00Z</updated>
    <summary>The code is super clean, though i did need to get into &amp;#39;functional
programming mode&amp;#39; to get it (took me about 5 minutes to understand
what was going on).

Currying is academically super interesting, but I think it&amp;#39;s more
useful in languages l...</summary>
    <content type="html">&lt;p&gt;The code is super clean, though i did need to get into 'functional&lt;br&gt;
programming mode' to get it (took me about 5 minutes to understand&lt;br&gt;
what was going on).&lt;/p&gt;

&lt;p&gt;Currying is academically super interesting, but I think it's more&lt;br&gt;
useful in languages like Haskell.&lt;/p&gt;

&lt;p&gt;If I were to write a double lambda which curried a multiply lambda,&lt;br&gt;
for instance, I'd just do this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;multiply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I think this is a lot less scary than a generalized currying lib, and&lt;br&gt;
just as powerful.&lt;/p&gt;

&lt;p&gt;Maybe I'm missing a killer use case though.  The method aliasing is&lt;br&gt;
definitely cool:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But what does that get me over:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I think the problem with Ruby is it doesn't need stuff like this. :)&lt;/p&gt;</content>
    <author>
      <name>Gregory</name>
    </author>
  </entry>
  <entry>
    <title>Currying</title>
    <link rel="alternate" href="http://graysoftinc.com/higher-order-ruby/currying"/>
    <id>tag:graysoftinc.com,2006-02-22:/posts/10</id>
    <updated>2014-03-28T21:20:00Z</updated>
    <summary>In this sixth article of the Higher-Order Ruby series, I examine currying by building up a currying library.</summary>
    <content type="html">&lt;p&gt;All the examples in this chapter are trivially translated (switch &lt;code&gt;sub { ... }&lt;/code&gt; to &lt;code&gt;lambda { ... }&lt;/code&gt;).  Ironically, I have never seen a chunk of idiomatic Ruby do anything like this.  Rubyists clearly favor blocks for this sort of work.  Have a look at the stream addition and multiplication examples of this chapter, for example.  You can also see this when MJD trying to create a suitable &lt;code&gt;inject()&lt;/code&gt; for Perl (he calls it reduce/fold).&lt;/p&gt;

&lt;p&gt;Another interesting point about this chapter is how much of it is spent warring with Perl's syntax.  MJD really struggles to introduce a block-like syntax for curried methods and is outright defeated in a couple of attempts.  I really like how easily Ruby yields to our attempts to reprogram her, in sharp contrast to her sister language.&lt;/p&gt;

&lt;p&gt;Continuing that line of thought, here's my best effort at the Poor Man's Currying library:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Proc&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args_munger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args_munger&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args_munger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Module&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args_munger&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unlike the Perl, this feels like very natural Ruby to me.  You could argue that I struggle with Ruby's syntax because it's not easy to curry a block-taking method, but that seems like a minor issue.  (This is fixed in Ruby 1.9, which adds &lt;code&gt;Proc#curry&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Here are examples of me playing with my toy:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"curry"&lt;/span&gt;

&lt;span class="n"&gt;multiply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;triple&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;    &lt;span class="c1"&gt;# =&amp;gt; 10&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;         &lt;span class="c1"&gt;# =&amp;gt; 10&lt;/span&gt;
&lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;         &lt;span class="c1"&gt;# =&amp;gt; 15&lt;/span&gt;
&lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Howdy "&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "Howdy Howdy Howdy "&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Value&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;curry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:triple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;five&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;howdy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Howdy "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;five&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="c1"&gt;# =&amp;gt; 10&lt;/span&gt;
&lt;span class="n"&gt;five&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; 10&lt;/span&gt;
&lt;span class="n"&gt;five&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;triple&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; 15&lt;/span&gt;
&lt;span class="n"&gt;howdy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;triple&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; "Howdy Howdy Howdy "&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I am purposefully trying to show the library's flexibility in these calls.  The version in the book only supports currying a single argument at the front of the list.  In 15 lines the Ruby version can completely rewrite arguments as it sees fit and it includes OO support.&lt;/p&gt;

&lt;p&gt;You be the final judge, but I stand by my claim that Higher-Order Perl is the quest to bring many Rubyisms to Perl.&lt;/p&gt;

&lt;p&gt;If you want to go deeper down the rabbit hole of currying in Ruby, I recommend you check out the Ruby library &lt;a href="http://rubygems.org/gems/rubymurray"&gt;Murray&lt;/a&gt;.  If you want to see a more Rubyish example of the &lt;code&gt;FlatDB&lt;/code&gt; MJD builds in these pages, also see &lt;a href="/ruby-tutorials/code-as-a-data-type"&gt;my article on code blocks&lt;/a&gt;.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
</feed>
