
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 http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html ). 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 standard. (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 http://www.boost.org/doc/html/function.misc.html#id2517594 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 because 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@cc.gatech.edu)