# Functor Opinion

**URL:** <https://www.ruby-forum.com/t/functor-opinion/83853>\
**Category:** Ruby\
**Created:** [March 19, 2006, 12:16pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853 "2006-03-19T12:16:57Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 12:16pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/1 "2006-03-19T12:16:57Z")

</div>

So here’s the Functor class:

class Functor \< BasicObject  
def initialize(\*obj, &func)  
@obj = obj  
@func = func  
end  
def method\_missing(op, \*args)  
if @obj.empty?  
@func.call(op, \*args)  
else  
@func.call(op, \*(@obj + args))  
end  
end  
end

Anyone who has seen the older version of this cllas will notice that I  
have added the \*obj parameter. This allows the Functor to act like a  
simple delegator too. But strictly speaking it isn’t at all necessary  
since one could just use the object(s) passed to the initialize  
directly in the block. Eg.

foo = 1  
Functor.new(foo) { |op, obj, \*args| obj.send(op, \*args) }

is the exact same as

foo = 1  
Functor.new { |op, \*args| foo.send(op, \*args) }

The only time this really is a little more handy is when passing  
‘self’, because of the ambiguity between contexts. Eg.

Functor.new(self) { |op, obj, \*args| obj.send(op, \*args) }

vs.

slf = self  
Functor.new { |op, \*args| slf.send(op, \*args) }

Not a big deal but there it is. Is there any other reason anyone can  
think of that the \*obj parameter is acctually needed or more convenient  
vs. direct reference in the block itself? If not, is it worth keeping,  
or should I just get rid of the \*obj parameter altogether?

Settling that issue, I’d like to request that the Functor class be made  
part of Ruby’s standard library. It is simple, generic and generally  
useful --I have had use for it myself on more than a few occasions now  
across multiple projects.

Thanks,  
T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 1:34pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/2 "2006-03-19T13:34:43Z")

</div>

Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> else
> 
> ```
> 
> worth keeping, or should I just get rid of the \*obj parameter  
> altogether?
> 
> Settling that issue, I’d like to request that the Functor class be  
> made part of Ruby’s standard library. It is simple, generic and  
> generally useful --I have had use for it myself on more than a few  
> occasions now across multiple projects.

I’m not the one who ultimately will decide whether something goes into  
Ruby’s standard lib or not. But I have doubts in this case. I cannot  
recognize a clear cut task of this class; it’s very generic and doesn’t  
really do much apart from propagating (delegating) arbitrary method  
calls.  
I’m not even sure that the name is appropriately chosen. If one looks  
at  
the definition in Wikipedia at

> **[Function object](https://en.wikipedia.org/wiki/Function_object)**
>
> In computer programming, a function object\[a\] is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax (a function parameter that can also be a function). In some languages, particularly C++, function objects are often called functors (not related to the functional programming concept).
> A typical use of a function object is in writing callback functions. A callback in procedural languages, such as C, may be performed by using func...

a functor needs at least the syntactic looks of a function. In the case  
of  
Ruby, implementing #[] and / or #call seems to be a minimum requirement.

Can you elaborate a bit more the benefits and use cases of this class?  
Thanks!

Kind regards

```
robert

```

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 1:40pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/3 "2006-03-19T13:40:23Z")

</div>

Hi –

On Sun, 19 Mar 2006, Trans wrote:

> ```
> else
> 
> ```
> 
> Functor.new(self) { |op, obj, \*args| obj.send(op, \*args) }
> 
> vs.
> 
> slf = self  
> Functor.new { |op, \*args| slf.send(op, \*args) }

You shouldn’t need to do that, though; self will be preserved from the  
context of the block’s creation:

```
 class C
 def f(&b)
   b.call
 end

```

end

C.new.f { puts self } # main

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 3:19pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/4 "2006-03-19T15:19:00Z")

</div>

> You shouldn’t need to do that, though; self will be preserved from the  
> context of the block’s creation:
> 
> ```
> class C
> def f(&b)
> b.call
> end
> 
> ```
> 
> end
> 
> C.new.f { puts self } # main

Thanks David I stand corrected on that point. I was confusiing it with  
define\_method blocks.

So even less reason to keep the \*obj parameter? Hmm…if I added a  
method to access those objects, then at least it could be used as  
reference to what objects might be involved. That seems like a fair  
usage.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 4:41pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/5 "2006-03-19T16:41:47Z")

</div>

On Mar 19, 2006, at 12:33 AM, Trans wrote:

> Settling that issue, I’d like to request that the Functor class be  
> made  
> part of Ruby’s standard library. It is simple, generic and generally  
> useful --I have had use for it myself on more than a few occasions now  
> across multiple projects.

Can you give example of where you used it?

James Edward G. II

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 3:15pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/6 "2006-03-19T15:15:13Z")

</div>

> Can you elaborate a bit more the benefits and use cases of this class?  
> Thanks!

Sure.

I’m aware that technically a Functor is nothing more than a first class  
function. But Ruby already has a class for this, Proc (not to mention  
Method). The class I present could more precisely be labeld a  
“MetaFunctor”. But since there’s nothing of use to define as Functor in  
Ruby I just dropped the “Meta” prefix. I’m all ears, if anyone has a  
truly better name.

One could define #call and #[] for this class too, but we don’t really  
want to, because we want to keep as many methods available for passing  
thru to method\_missing as possibe. (Hence the subclass of BasicObject,  
ie. BlankSlate).

I generally use it to create a separate method space for a class.  
Here’s an example of one place I’ve used it:

# facet/kernel/ **meta**.rb

begin  
require ‘calibre/functor’  
rescue LoadError  
require ‘facet/functor’  
end

class Object

# Returns a Functor that allows one to call any

# Kernel method bound to self.

# 

# class A

# def object\_id ; “OBTUSE” ; end

# end

# 

# c = C.new

# c.object\_id #=\> “OBTUSE”

# c. **meta**.object\_id #=\> 6664875832

# 

def **meta**  
@ **meta** ||= Functor.new do |meth, \*args| # &blk|  
Kernel.instance\_method(meth).bind(self).call(\*args) # ,&blk)  
end  
end

end

Additionally, the Functor can also be used as a quick and simple  
delegator or proxy.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [March 19, 2006, 4:54pm UTC](https://www.ruby-forum.com/t/functor-opinion/83853/7 "2006-03-19T16:54:04Z")

</div>

> Can you give example of where you used it?

Check two posts back at ‘facet/kernel/ **meta** ’. Here’s another for a  
project I’ve been working on this week:

class Program

```
# ...

def self.compile( yml, prg=nil )
  prg ||= Program.new

  sig = (class << prg; self; end)
  yml.each { |key, val|
    case val
    when RubyFn
      #val.out = val.out || key
      sig.class_eval {
        define_method( key ) { eval( val.code ) }
      }
    when Fn
      sig.class_eval {
        define_method( key ) { calc( val.code ) }
      }
    when Hash
      sig.class_eval {
        ftr = Functor.new { |op, *args| prg.send(op, *args) }
        res = compile( val, ftr )
        define_method( key ) { ftr }
      }
    when Type
      # do nothing
    else
      sig.class_eval {
        define_method( key ) { val }
      }
    end
  }

  return prg
end

```

end
