
David Abrahams wrote:
Thomas Witt <witt@acm.org> writes:
David Abrahams wrote:
The second half of that sentence sounds rather sweeping and extreme.
Please don't read to much into it. It's just that I have serious doubts.
It me took about 10 re-readings of this email to guess that us == the library developer and the component is, e.g. a pre-existing component like std::vector or builtin arrays. Did I get that right?
Sorry for not being more clear. You are basically right. Us means boost or boost::range in particular.
In order to have our cake and eat it we move our interface in our own namespace where we are free to do whatever we see fit.
I don't see it that way. If we're using the strategy discussed here -- which I'm not claiming is ideal -- we do that part just to keep other authors of generic code from having to remember to write ugly using declarations.
I would not want to describe using declarations as ugly. They clearly describe the intent of the programmer. Though I do agree that forgetting about them is a very likely cause of error.
In other words, aside from that ugly using declaration, which is needed to make the interface truly generic, the interface lives in the "global ADL space."
The point that I am concerned with is _which_ interface adds up in the "global ADL space". IIUC the ADL hooks boost_range_begin etc. end up there. AFAICS these are not meant to be used by a user of a library, are they?
I guess if you view the using declaration as a kind of namespace qualification, you could see this as moving the interface into our namespace.
I was talking about functions like begin(), end() those end up in the boost namespace, don't they.
The problem being that we cannot provide the interface for all types out there but we still want this to be extensible. Furtheremore we sure don't want anybody to invade our namespace
I don't think we care about that last part, provided they do it in a way prescribed by us. Certainly, specialization is a kind of invasion, and that's no problem. The problem becomes that inviting the user to invade our namespace with _overloads_ just doesn't work because ordinary lookup is limited to what's visible at the point-of-definition.
I got carried away in my writing. I am aware of the issue, if only for the reason of getting bitten by ignorance in the past.
So what does that mean for the other libraries out there? They have to clutter their interface with these hooks that are meant only for communication with the boost library and that are useless if the user of the other library does not use boost.
Not if you buy Peter Dimov's argument that many customization points become "public domain" and are no longer the property of any library. Read that part of the thread carefully. Once people start supplying begin() hooks, other library authors may start making interfaces that work with Boost.Range compatible types.
I've read through his argument at least twice in the past. That being said I might still not get the point. I do agree with the names becomming public domain. What I disagree with is that names like boost_range_begin are suitable for this. They will likely always be warts in an interface.
Apart from the fact that the hook strategy is unlikely to scale well (how many potentially useless hooks do you want in your library?)
In my library? Useless? I'm confused. Am "I" the author of a library component who is trying to get it to work with other libraries like Boost.Range?
Just assume you are.
Something like begin(x), if I'm the author of a container type, seems useful to me!
Yes begin() but not boost_range_begin()
It might be used by anyone wanting to write composable generic algorithms over sequences. One of the problems with the STL interface is that composing the algorithms is more cumbersome than it should be.
I am all for a range concept. I am at odds with the proposed solution for that. Thomas