Enumerable#every, the Functor and Ruby support for HOM

Have you heard of Enumerable#every? It lets you apply a method call to
all elements of an enumerable. Check it out…

[1,2,3].every + 3 #=> [4,5,6]

[1,2,3].every * 3 #=> [3,6,9]

words = [“hello”, “world”]
words #=> [“HELLO”, “WORLD”]

Essentially every is a convenient and nicely readable “fluent notation”
alternative to using a map/collect block.

Now you might be wondering how this bit of magic is achieved? Here is

module Enumerable
   def every
      Functor.new do |op,*args|
        map{ |a| a.send(op,*args) }

As you can see it works via something called a “Functor”. Generally
speaking, a “functor” is simply an object that encapsulates a function.
this case I have used the term as a concise reference to a specialized
of such to achieve Higher Order
. The basic definition of this class is:

class Functor
def initialize(&function)
@function = function
def method_missing(op, *args, &blk)
@function.call(op, *args, &blk)

This Functor class can be used in many many ways. Enumerable#every is
one of many examples. In fact, Ruby’s own Enumerator class is actually
a highly specialized type of Functor.

As useful as a Functor can be, it does however have two downsides. First
depends on #method_missing. This means public Object methods
can interfere with its usefulness. This can be worked around by making
Functor a subclass of BasicObject. Though a few public methods remain,
is good enough for all practical purposes. A more problematic issue is
fact that it requires the creation of an indeterminate object every time
the a method using a Functor is called. This is pretty inefficient,
things down and requires us to be memory conscious. Caching can be used
some cases, but rarely is it an ideal fix.

Recently I came up with an idea that would allow these issues to be
circumvented entirely. I realized that since this is a higher order
message, then really it would be best handled as a messaging issue
–hence via the definition of a “higher order method”. In other words if
Ruby had built-in support for the concept, the intermediate object would
not be necessary and consequently interfering public methods would not
exist. To facilitate this, I came up with a potential notation. Here’s
it would be used to define Enumerable#every:

module Enumerable
  def every => op, *args
    map{ |a| a.send(op,*args) }

(Hmm… as I typed this it occurs to me that maybe => would be more
intuitive if it pointed the other way using <=.) Regardless of the
notation used, the idea is to allow Ruby to handle higher-order-messages
internally as a special type of method.

For reference here are a few other examples of using Functor:



P.S. There is also a functor gem out there, but it is not the Functor as
defined above. The functor gem came along well after the one described
(which is included with Ruby F.s). The gems’s implementation is
basically a kind of struct that supports multiple dispatch capabilities.
The above is much more generic and actually can even be used to create
functor gem’s more specialized kind with just a bit of extra code.