|
Boost Users : |
From: David Abrahams (dave_at_[hidden])
Date: 2005-03-06 23:22:31
"Peter Dimov" <pdimov_at_[hidden]> writes:
> It is actually not _that_ unreasonable to put ADL customization point
> defaults in the global namespace and dispense with the "using" idiom.
> Moderately unreasonable, maybe. :-)
I'm interested in why you say that. After all, the likelihood of
collision is infinitesimal, right? ;-)
>>> Consider get_pointer. It was once "the protocol that mem_fn uses
>>> when faced with a smart pointer" and was not required to return a
>>> raw pointer. Now it's "the way to obtain a raw pointer from a
>>> pointer-like object" and is no longer used by mem_fn (in its TR1
>>> incarnation). If this isn't an example of how the customization
>>> point is not owned by the library, I don't know what is. ;-)
>>
>> I don't know if citing a library evolution for which you hold all the
>> responsibility really counts. ;-)
>
> I am not responsible for the evolution of get_pointer. tr1::mem_fn doesn't
> even use it.
So who's using it? [And why doesn't mem_fn use it?]
>>>>> The implication of that is that customization points need to be
>>>>> minimized and their semantics - carefully chosen. They are even
>>>>> more important than the (rest of the) public interface of the
>>>>> library, because they can affect and shape the code of people
>>>>> that don't even use this particular library.
>>>>
>>>> So does the rest of the public interface.
>>>
>>> The rest of the public interface does not affect non-users.
>>
>> I don't get it. Even if author A has to glom a giant ugly fribsackle
>> onto his type so that it can satisfy library B's concept requirements,
>> author C can use A's type with B's functions without ever having to
>> confront the fribsackle herself.
>
> Um, I beg your pardon? ;-)
Having a problem with the term "fribsackle?"
> Library B defines requirements. Author A satisfies them by defining a
> function or specializing a class template. Author C uses A's public
> interface, which _includes_ the function or the specialization. Ergo, B's
> customization points
Aha! So you admit B owns these customization points! ;-)
> affect C, who does not use B and may not even have heard of it.
You apparently view these implementations of B's customization points
as part of A's interface. But these customizations might be supplied
by a third party, adapting A to B (yes, I know there's a problem when
multiple third parties get involved). I tend to see them as something
A does for B's benefit, and not neccessarily for the rest of the
world.
>>>> I'm not sure about the weight you're giving to these things.
>>>> People supply these customization points at most once per
>>>> component, and it's a "private matter between two consenting
>>>> programmers." It doesn't need to affect other users of either
>>>> programmers' code -- unless of course you have to worry about
>>>> future name collisions ;-)
>>>
>>> A customization point is a public protocol that needs to be followed
>>> by types in order to advertize a certain property or operation. I
>>> don't see how it can be a private matter. Library A introduces
>>> customization point f(x), library B defines f(y) for its type Y,
>>> library C uses f(x) in order to benefit from the fact that there are
>>> already types Y that support the protocol. These three libraries are
>>> totally separate.
>>
>> You mean that the customization point is automatically up-for-grabs
>> for any library to use, as soon as you advertise that it makes a type
>> work with some particular library.
>>
>> Well, I guess that's the difference between specialization and
>> overloading. With specialization, you sorta need to have one of that
>> library's headers around to get the declaration.
>
> It doesn't matter, really. If the customization point is useful, it
> will be used. The customization points define the interface of a
> domain-specific class, to use your terminology.
I don't view the class as domain-specific neccessarily. Most classes
will cross domains. For example, swap, from the value-type domain,
applies to almost everything. I also don't view those things as
really being the interface of a class. That piece of interface
was defined and specified by someone else.
Maybe when you say "class" you mean something like "Concept,"
i.e. swappable?
> This interface will then be picked up by others.
>
> Of course you _could_ define the customization point in such a way
> so that its usefulness to others is minimized.
Heh, yes.
> Eh, of course one wouldn't use iterator_traits<>::difference_type in such a
> way, but I wouldn't expect you to define this kind of a customization point.
> You would define difference_type<X>::type, probably, to which your
> objections do not apply.
Right.
> Anyway, my point was just that good customization points transcend a
> specific library, if not the whole domain.
You seem to have a point.
> iterator_traits isn't an example of a good customization point.
Tell me (all) about it.
>>> Right. But "introduced by" and "owned by" are not the same thing.
>>> Once it's introduced and adopted, the genie is out of the bottle.
>>
>> What is your meaning for "owned by?"
>
> Controlled by. Something that you can change the specification
> of. Something that you can change the name of. Something you can
> change the namespace of, if you will.
Okay.
>>> I don't like domain tags much. Seems like a fairly high price to pay
>>> for dubious returns.
>>
>> What's the cost, overall? You may "need" such an interface
>> dispatching function anyway, to deal with builtin types.
>
> The cost is the extra parameter and the dependency on the tag header, and
> with the utility function infrastructure in place, a class template instead
> of a tag isn't very far.
But they have many disadvantages, including not matching derived classes.
>>> I only use such tags when I need to inject a namespace for
>>> ADL purposes via the tag.
>>
>> Example, please?
>
> I'll need to think about it. A quick scan doesn't reveal anything similar,
> so I might have dropped this technique. I _think_ that it had to do with the
> fact that one can't put overloads into std. I had an ADL interface f(x, y),
> where the x'es came from different namespaces, and I needed to define f( _,
> std::vector ). I see in the code that I have "solved" this problem by
> putting all x'es in the same namespace. What a hack. ;-) The other option
> was to add a tag and put the std:: related overloads in that tag's
> namespace.
Thanks.
> Maybe I'll just bite the bullet and start putting overloads in std instead
> one day.
Live dangerously or don't live at all ;-)
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net