From: David Abrahams (dave_at_[hidden])
Date: 2003-10-10 06:16:25
Mat Marcus <mat-boost_at_[hidden]> writes:
>>> Yes! At the risk of repating myself from the recent "Beyond Objects"
>>> thread: Down with members, nested types and trais, in public
>>> interfaces :-)
>>> It's that darned OO mentality that's so hard to shake loose on the
>>> way to generic design. Having the return type calculator as a free
>>> metafunction seems like just the ticket.
>>>> Hmm. Is there some point in the design space here that optimizes
>>>> all of the various considerations?
>>> Hmm. Good question.
>> The usual trick is the same one used by iterator_traits:
> (Incidentally, I'd like to see iterator_traits broken up into free
> generic metafunctions too.)
Of course. I thought we already started that in the new iterator
adaptors stuff, but I don't see it.
>> the default implementation (unspecialized version) dispatches to
>> some member, for convenience.
> Yes, of course. This is a natural idea. One problem that I've seen
> with this technique is that sometimes would-be generic
> (meta-)algorithm authors forget to indirect through the traits class.
> Maybe it would be a service when providing a library that works using
> such indirection to also provide archetypal instances with no nested
> data and appropriate specializations for algorithm authors to test
> against. IIRC the boost concept lib employs the same technique.
> In any case I think this is the right track. It seems that today
> various libs, MPL included, may place too many constraints on their
> collaborators. Instead of assuming that a quoted metafunction, er
> excuse me, metafunction class ;-) has a nested apply<> why not use a
> level of indirection and have it adhere to a metaconcept instead. E.g.
> maybe its enough to require the concept that
mpl::apply<meta_function_class, T1, T2,... TN>::type
> is utterable and has the corect semantics. Then libs wouldn't have
> to be rewritten to internally follow designated naming
> conventions. Instead they could model the required concepts (or is
> that: metamodel the required metaconcepts) generically by providing
> certain free metafunctions.
You can carry this too far. Can you imagine a functional programming
library which didn't require nested operator(), and instead used an
external call() free function?
I think it's silly to externalize everything, and (meta)functions are
the kind of tiny single-purpose objects which can be allowed to have
constraints. Otherwise, why constrain your meta_apply either? And
then, how do you invoke it?
We only got here because of the multi-purpose roles of apply/sig and
operator() in full functoids ;-)
> You could even have headers such as
> functoid_as_meta_function_class.hpp following boost::graph's
> vector_as_graph.hpp (except avoiding traits) example so that the
> functionality could be added in layers, paying as you go. I am
> tempted to apply these heuristics to boost:: and std:: and see how
> various generic rewrites might look. The s/OO/generic/g rule would
> be something like, "whenever a nested type (or traits, which
> technically also use nested types) or a nested member (e.g. member
> function or member variable) is used, add a level of indirection so
> that collaborators have a chance to supply this function
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk