Boost logo

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