<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kevin&#039;s random thoughts &#187; deep magic</title>
	<atom:link href="http://kbullock.ringworld.org/tag/deep-magic/feed/" rel="self" type="application/rss+xml" />
	<link>http://kbullock.ringworld.org</link>
	<description>god, tech, and other geekery</description>
	<lastBuildDate>Wed, 01 Feb 2012 19:35:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Higher-order messaging</title>
		<link>http://kbullock.ringworld.org/2007/03/26/higher-order-messaging/</link>
		<comments>http://kbullock.ringworld.org/2007/03/26/higher-order-messaging/#comments</comments>
		<pubDate>Mon, 26 Mar 2007 12:01:00 +0000</pubDate>
		<dc:creator>kbullock</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[deep magic]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">/2007/03/27/higher-order-messaging</guid>
		<description><![CDATA[WARNING: Deep magic ahead! (and a very long article)

I stumbled on a concept called Higher-Order Messaging (HOM) today. It&#8217;s a handy way to allow an object-oriented language to call a message on all members of a collection without having to manually iterate over the collection, like so (Ruby):

[0, 1, 2].where.nonzero? =&#62; [1, 2]


That means &#8220;Give [...]]]></description>
			<content:encoded><![CDATA[<p><strong>WARNING:</strong> Deep magic ahead! (and a very long article)</p>

<p>I stumbled on a concept called <a href="http://www.metaobject.com/Research.html#HOM">Higher-Order Messaging (HOM)</a> today. It&#8217;s a handy way to allow an object-oriented language to call a message on all members of a collection without having to manually iterate over the collection, like so (Ruby):</p>

<pre><code>[0, 1, 2].where.nonzero? =&gt; [1, 2]
</code></pre>

<p>That means &#8220;Give me the subset of [0, 1, 2] where the item is nonzero&#8221;. Quite natural syntax, eh? The usual Ruby equivalent is:</p>

<pre><code>[0, 1, 2].select {|x| x.nonzero?}
</code></pre>

<p>which is a little more verbose. When I read the <a href="http://www.metaobject.com/Research.html#HOM">paper</a>, I jumped immediately to implementing their <code>select:</code> method in Ruby. Thus launched an afternoon of investigation that led me to some interesting conclusions.</p>

<pre><code>        &lt;span id="more-60"&gt;&lt;/span&gt;

        &lt;h3&gt;Say what now?&lt;/h3&gt;
</code></pre>

<p>The name &#8220;higher-order messaging&#8221; comes by analogy with <a href="http://en.wikipedia.org/wiki/Higher_order_function">higher-order functions</a>, as known in functional languages. In a language that supports higher-order functions, a function can be passed as a parameter to another function. The analogy, then, is that a message can take another message as a parameter. In the above example, that presumably means you&#8217;re passing the <code>#nonzero?</code> message as a parameter to the <code>#where</code> message; the <code>#where</code> method then calls <code>#nonzero?</code> on each item in the array.</p>

<p>But wait, that&#8217;s not quite right. Syntactically, you&#8217;re calling <code>#nonzero?</code> on the <em>result</em> of <code>#where</code>. That&#8217;s not at all the same as &#8220;passing <code>#nonzero?</code> as a parameter to <code>#where</code>&#8220;.</p>

<p>Well, &#8220;higher-order messaging&#8221; is a misnomer. What you&#8217;re actually doing is sending a message to a proxy object that&#8217;s returned by the &#8220;higher-order method&#8221;. Then, whatever message you send the proxy object, it sends that message to every member of the Enumerable it&#8217;s proxying.</p>

<h3>First implementation</h3>

<p>Here&#8217;s the code:</p>

<pre><code>module Enumerable
  # 'select' is already taken
  def where
    WhereProxy.new(self)
  end
end

class WhereProxy
  def initialize(enum)
    @enum = enum
  end

  def method_missing(meth, *args, &amp;block)
    @enum.select { |x| x.__send__(meth, *args, &amp;block) }
  end
end
</code></pre>

<p>This is the natural first implementation. Your enumerable object gets a <code>#where</code> method that returns a proxy object that works as described above.</p>

<p>Once I got to this point, I looked around to see if anyone else had implemented HOM in Ruby already. <a href="http://nat.truemesh.com/archives/000535.html">Someone had</a>, of course; and someone else <a href="http://legacyofthemob.se/istari/2006/10/08/higher-order-messaging-in-ruby/">improved upon it</a>. Let&#8217;s take a look at these.</p>

<h3>Another implementation</h3>

<p>The first aforementioned implementation works about like my first implementation, but a little bit generalized. First, the author creates a superclass for all the proxy classes we&#8217;ll write (paraphrased from <a href="http://nat.truemesh.com/archives/000537.html">here</a>):</p>

<pre><code>class HigherOrderMessage
  instance_methods.each do |method|
    undef_method(method) unless method =~ /__(.+)__/
  end

  def initialize(obj)
    @obj = obj
  end
end
</code></pre>

<p>This saves us from having to write the same constructor for every proxy class; it also undefines every method it inherits from <code>Object</code> except <code>#__id__</code> and <code>#__send__</code> (the absolutely essential ones), so <em>any</em> method we call will be passed to the proxied object (including <code>#id</code> and <code>#send</code>!). To write a proxy class for a particular method, we subclass <code>HigherOrderMessage</code> and implement <code>#method_missing</code> to actually proxy messages as desired (paraphrased again):</p>

<pre><code>class WhereProxy &lt; HigherOrderMessage
  def method_missing(meth, *args, &amp;block)
    @enum.select { |x| x.__send__(meth, *args, &amp;block) }
  end
end
</code></pre>

<p>Now that we have our proxy class, we can implement the method that returns an instance of it (again, paraphrased):</p>

<pre><code>module Enumerable
  def where() Where.new(self); end
end
</code></pre>

<h3>An improvement</h3>

<p>Okay, so this leaves us implementing a lot of classes, and a lot of methods that instantiate those classes and return the instance. (How very Java-y.) That&#8217;s a definite <a href="http://c2.com/cgi/wiki/wiki?CodeSmell">code smell</a>, especially in Ruby. There must be a more terse way; the <a href="http://legacyofthemob.se/istari/2006/10/08/higher-order-messaging-in-ruby/">second implementor</a>, of course, recognized this. Here&#8217;s the second implementation (paraphrased):</p>

<pre><code>class HigherOrderMessage
  instance_methods.each do |method|
    undef_method(method) unless method =~ /__(.+)__/
  end

  def initialize(&amp;block)
    @block = block
  end

  def method_missing(meth, *args)
    @block.call(meth, *args)
  end
end
</code></pre>

<p>See what happened there? Now, instead of <em>subclassing</em> <code>HigherOrderMessage</code> and implementing <code>#method_missing</code>, we just pass a block to the constructor, and that block *is* our specific <code>#method_missing</code> implementation. No subclassing needed.</p>

<p>So to actually implement a higher-order method, we return an instance of <code>HigherOrderMessage</code> with the proper code block. This gets us pretty far; we can even &#8220;chain higher-order methods&#8221; (rather innacurate terms) to create some interesting effects:</p>

<pre><code>module Enumerable
  def every
    HigherOrderMessage.new do |meth, *args|
      self.each { |x| x.__send__(meth, *args) }
    end
  end

  def where
    HigherOrderMessage.new do |meth, *args|
      self.select { |x| x.__send__(meth, *args) }
    end
  end

  def all
    HigherOrderMessage.new do |meth, *args|
      self.collect { |x| x.__send__(meth, *args) }
    end
  end

  def do_inject(start_value)
    HigherOrderMessage.new do |meth, *args|
      self.inject(start_value) { |a, x| a.__send__(meth, x, *args) }
    end
  end

  def having
    HigherOrderMessage.new do |id, *args|
      HigherOrderMessage.new do |secid, *secargs|
        select { |x| x.__send__(id, *args).__send__(secid, *secargs) }
      end
    end
  end
end

[0,1,2,3,4].where.nonzero? =&gt; [1,2,3,4]
[0,1,2,3,4].do_inject(0).+ =&gt; 10
[0,1,2,3,4].having.succ &lt; 3 =&gt; [0,1]
</code></pre>

<p>Catch that last one? That means &#8220;give me each element of [0, 1, 2, 3, 4] whose succeeding value is less than three&#8221;. Neat, huh?</p>

<h3>Can we still do better?</h3>

<p>There&#8217;s still a couple ways we can do better, though, and here&#8217;s where my own innovations start. First off, a lot of the implementations of iteration functions look the same. Can we find a way to avoid repeating all that nasty block-construction code? What I want is this:</p>

<pre><code>module Enumerable
  define_curried_method(:every, :each)
  define_curried_method(:where, :select)
  define_curried_method(:all, :collect)
end
</code></pre>

<p>&#8230;that is, I know that <code>#each</code>, <code>#select</code>, and <code>#collect</code> all have the same signature (and their blocks all do too), even though they do different things. Can&#8217;t I write some meta-code to give me higher-order versions of these? Here&#8217;s how we do it:</p>

<pre><code>class Module
  private
    def define_curried_method(name, method)
      define_method(name) do
        HigherOrderMessage.new do |sym, *args|
          self.__send__(method) { |x| x.__send__(sym, *args) }
        end
      end
    end
end
</code></pre>

<p>Making our new <code>define_curried_method</code> syntax a private instance method of Module puts it on par with <code>attr_accessor</code> and friends, so now our nice, terse higher-order method definitions on Enumerable work as expected.</p>

<p>Another problem is that there&#8217;s currently no way we can pass a block to the method we&#8217;re calling on every object in the collection. For example, if we have an array of strings and want to do the same substitution on all of them, here&#8217;s what we need:</p>

<pre><code>%w[an array of strings, some with double letters].all.gsub(/(.)\1/) do |match|
  (match == 'rr' ? 'ARRRR' : match)
end
=&gt; ["an", "aARRRRay", "of", "strings,", "some", "with", "double", "letters"]
</code></pre>

<p>Well, with a few modifications, we can make it work. There&#8217;s a snag, though; unlike methods, blocks in Ruby can&#8217;t take a block as their last parameter, since there&#8217;s no way to pass a block to a block, syntactically speaking. We can push a block onto an array, though, and that means we <em>can</em> pass a block to a block. The trick is that the receiving block needs to know how to call the block it was passed. Going back to our simpler, less automatic implementation:</p>

<pre><code>module Enumerable
  def all
    HigherOrderMessage.new do |meth, *args|
      if args.last.is_a? Proc then block = args.pop; end
      self.collect { |x| x.__send__(meth, *args, &amp;block) }
    end
  end
end
</code></pre>

<p>This is a start, but how does the <code>args</code> array get the block we pass as its last item? We need to catch the block in <code>HigherOrderMessage#method_missing</code> and push it onto the argument array for the block:</p>

<pre><code>def method_missing(meth, *args, &amp;block)
  args &lt;&lt; block if block_given?
  @block.call(meth, *args)
end
</code></pre>

<p>Okay, that&#8217;s all well and good, but now we&#8217;ve lost the <code>define_curried_method</code> macro, <em>and</em> we have an extra line to write in the block in each of our higher-order method implementations. Can we fix our current macro implementation?</p>

<pre><code>class Module
  private
    def define_curried_method(name, method)
      define_method(name) do
        HigherOrderMessage.new do |sym, *args|
          if args.last.is_a? Proc then block = args.pop; end
          self.__send__(method) do |x|
            x.__send__(sym, *args, &amp;block)
          end
        end
      end
    end
end
</code></pre>

<p>There we go. Now we can pass blocks to our curried methods, and it&#8217;ll all work! Arrrrr!</p>

<pre><code>%w[an array of strings, some with double letters].all.gsub(/(.)\1/) do |match|
  (match == 'rr' ? 'RRRR' : match)
end
=&gt; ["an", "aRRRRay", "of", "strings,", "some", "with", "double", "letters"]
</code></pre>

<h3>Limitations</h3>

<ol>
<li>We can&#8217;t use the macro to implement our <code>#do_inject</code>, because the method it writes only passes one argument to the block; <code>#inject</code> needs two arguments to its block.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://kbullock.ringworld.org/2007/03/26/higher-order-messaging/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

