
On Mon, May 19, 2008 at 1:37 PM, Marco Costalba <mcostalba@gmail.com> wrote:
On Mon, May 19, 2008 at 4:26 PM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
a placeholder. Placeholders indicate a template parameter in the function's argument list (not an unspecified function object outside the argument list). Actually, come to think of it, _1(_1, _1) would probably not be possible because it doesn't encode the type of a polymorphic function object, so there's no way for the compiler to use that type's set of overloaded operator()s later on at the call site. _1(_1,_1) is type erasure again and that breaks polymorphic function objects.
Well, the first _1 is intended to be the return type, not the polymorphic type.
Aha, my bad, I misunderstood you. You intended the first _1 to indicate a variable return type, right? That's not a bad idea, except we already have an expression to indicate that a function has a variable (a.k.a. argument dependent) return type - the signatures of the result_of protocol. The signature protocol I'm defining is identical to the result_of protocol except that it can additionally use MPL placeholders in the argument list to represent template parameters (and it handles reference_wrapped functors).
It's _1(_1, _1) because plus and minus return T: T plus(T, T), T minus(T, T)
So it's bool (T) because is_positive and is_negative return a bool.
Actually I think there is no way to create a polymorphic functor wrapper, but anyway it's the logical extension of function signatures in the polymorphic world because function signatures do not imply _any_ algorithm or functionality apart from arguments and return type.
By extending the protocol used by result_of to include placeholders representing template parameters in the argument list, we can wrap polymorphic functors without loss of polymorphism. The file I sent earlier includes a unary implementation of such a call-wrapper called polymorphic_function.
So a poly signature should define return type and arguments ONLY. Because here we talk about templates, i.e. family of types and not a single type we can only specify argument arity and when argument types should be the same, as in plus, or different as _3(_1, _2)
See, I think it should extend the result_of signature's protocol for encoding variable return types... again, by specifying a callable object type in the first position of the signature. Also of interest, Shunsuke Sogame has an experimental multi-signature call-wrapper that uses a very similar signature protocol complete with placeholders representing template parameters (see the Egg review result thread). So, I think this notion of a polymorphic signature composed of a callable object type and optional MPL placeholders is probably a good way to go.
I would think overload_set is based on the concept of wrapping a function (call it type erasure), but when you assign plus(_1,_1) there is nothing to wrap, just use plus instantiated by compiler according to the calling sites arguments.
If you need a generic fallback it is better to let overload_set derive directly from plus() and you have what you need.
The goal that I have in mind is to achieve call-wrapping (that is call deferral, type-erasure is optional) of both builtin functions and what we could call rank-n polymorphic functors - function objects with overloaded/templated operator(). (The generic fallback is just an example application of such a call-wrapper.) To do these two things, we need two signature protocols: a normal boost::function-style call signature for monomorphic builtins and a result_of-style "polymorphic" signature with placeholders for rank-n functors. So, for example, the problem is not wrapping, deferring, or dispatching plus. The problem is managing both signature protocols so that the same call-wrappers (polymorphic_function and by extension overload_set) are generic enough to handle both pointers to monomorphic builtins and instances of rank-n functors. So, I'm advocating the following division of labor: polymorphic_function manages the two signature protocols and can defer a single callable object. overload_set uses polymorphic_function to defer multiple callable objects. See what I'm getting at? Daniel Walker