Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2008-05-19 23:35:25


On Mon, May 19, 2008 at 1:37 PM, Marco Costalba <mcostalba_at_[hidden]> wrote:
> On Mon, May 19, 2008 at 4:26 PM, Daniel Walker
> <daniel.j.walker_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk