Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2004-02-19 12:58:20

On Thu, Feb 19, 2004 at 02:58:12AM -0500, Gennadiy Rozental wrote:
> C++ standard introduces and STL uses notion of function object a generic
> abstraction for function. By design it is structure type with non-template
> operator(), where types of the arguments and result types are unambiguously
> defined by the type of function object (it could be hardcoded types or types
> dependent on structure template parameters). So let's call it monomorphic
> function object, opposed to the alternative design for function object,
> which uses member template operator() which we will call polymorphic
> function object. Polymorphic function objects in some ways better/more
> powerful than monomorphic ones. But there is an issue of result type
> deduction, which require special support. Solution is described in mention
> by you paper and your library implements it (as I understand it).
> Now the question is why would we need separate notion of functoid, while
> we already have powerful abstraction for function objects presented by
> boost::function? Why boost function does not present this functionality (if
> it does not, I am not sure)? This looks like obvious place to implement this
> solution: you provide helper facilities to make it easier to write
> polymorphic function objects and you make boost::function polymorphic
> function object aware (even though it still be a model for monomorphic
> function object). This will cover indirect functoids also.

I am not sure exactly what you are asking/suggesting, but I think I get
the gist of it enough that hopefully I can answer anyway.

As a quick aside, let me define "adaptable" to mean a function object
which exports a way to ask about its return type (in the same general
sense as
). Also let me define "rebindable" to mean function objects which are
variables that can be bound to different function objects during the
variable's lifetime, as in
   boost::function<int (int,int)> f;
   f = _1+_2; // f is now "plus"
   f = _1-_2; // f is now "minus"

Given those definitions, functon objects can be generally classified
along 3 different axes:
 - they can be monomorphic or they can be polymoprhic
 - they can be adaptable or not
 - they can be rebindable or not

"Direct functoid" is just the term we use in FC++ to describe
adaptable, non-rebindable function objects. "Indirect functoid" is the
term for "adaptable, rebindable, monomorphic" function object.
boost::function objects are classified just like indirect functoids
(adaptable, rebindable, monomorphic).

My goal for the various "functoid" terms is not to introduce new
vocabulary, but rather merely to simplify the exposition. Hopefully
"standard" terms for these concepts will arise soon (I don't think they
have yet). In any case, a "standard" implementation for result-type
deduction has already arisen (result_of), and FC++ supports this

(Let me know if I still have not answered/addressed your question.)

> (BTW why do you
> need virtual for it's implementation - I did not see single one in
> boost::function)

This amazes me, though
maybe explains it. I still cannot quite fathom how "virtual" is avoided
in boost::function, but I look forward to exploring the code or chatting
with Douglas Gregor about it. :)

In any case, you need some kind of way to do the indirection, and we
chose virtual functions as our implementation.

> Currying: I have a question: why boost::function does not provide currying
> internally? Why do we need boost::bind? IMO polymorphic function object
> currying should be incorporated in boost::bind.

I see that others are currently discussing the pros and cons of this
in other messages on the list.

> Smartness: I believe boost::function interface may be extended a little if
> we find your addition convenient. But as for now arity seems to be good
> enough.

Indeed; also, FC++ and boost have a different notions "arity", so this
doesn't "blend" well into boost functions.

> Infix syntax: I am not sure I like the idea in a first place. But it could
> be discussed and added

It is more useful when you have "named" operators as in FC++, simply

   x ^plus^ y

is often more readable/natural than

   plus( x, y )

It may also be attractive to OO people, who have gotten into the
now-fashionable habit of avoiding member functions. Switching from
the member notation

   Shape s; Point p;
   if( s.contains(p) ) ...

to the non-member notation

   if( contains(s,p) ) ...

loses the subject-verb-object order; using function objects that support
infix, however, lets you say

   if( s ^contains^ p ) ...

which some people may find attractive.

Thanks for your comments!

-Brian McNamara (lorgon_at_[hidden])

Boost list run by bdawes at, gregod at, cpdaniel at, john at