
on Sat Jun 23 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Dave Abrahams wrote:
on Fri Jun 22 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Dave Abrahams wrote:
on Fri Jun 22 2012, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Sorry, I just can't understand why anyone fails to see this point.
Because, while it's true that it has those effects, that sort of thing happens all the time, and most of us see no reasonable way of stopping it without severely constraining Boost development.
Don't you regularly "inject new bodies of code" into Boost.Serialization that "replace lines and add no functionality used/needed by" Boost.MPI?
No. I don't do this.
I believe you mean that sincerely, but I just don't see how it's possible for you to know that. Do you keep track of exactly which of Boost.Serialization's headers is being used by every dependent Boost library and make sure that *no* new capabilities creep into any of those headers as you extend/evolve the library? Even if you _can_ do that for other Boost libraries, you can't possibly do it for your users.
I use other libraries in the implementation. These implementation details are generally not directly accessible by the library user.
Of course they are, if they end up in the user's translation unit. The user only has to have a "using namespace boost;" in his code to create an instant ambiguity when one of your "implementation details" adds a new name, or when you add a new implementation detail yourself. Blame it on the C language inclusion model. We need true modules in C++, but that's irrelevant to this conversation.
Any code injection/enhancement would be something that users would see in library portability, performance, robustness etc. It's my job to ensure that that is what happens.
You mean to ensure that it (users seeing changes in portability, performance, robustness, etc) *doesn't* happen?
Actually, you've hit the nail on the head here. Chaning boost::throw_exception injects a dependency on a whole other boost library into the serialization library. And of course this is the crux of my complaint.
In general it's hard for me to believe that you'd complain (or probably even ever notice) if one of the libraries you depend on as an "implementation detail" added a dependency of its own, and thereby injected a new dependency into Boost.Serialization... unless this change happened to break something. I assert that this kind of thing happens all the time: every Boost library author (well, maybe Peter Dimov is an exception) feels free to start using some new library as an "implementation detail" of his own.
Of course it was. Do you think the problems with boost::throw_exception were intentional?
I'm sure the changes were intentional. I think the dispute is about whether those changes are problems (my view) or useful features whose value far exceeds any side effects of the changes (other's view) that.
But surely you do change existing headers from time-to-time?
only to
a) fix bugs b) re-implement some existing interface c) add some new feature to the serialization library d) improve robustness, portability, etc.
note that this above list does not include changing the functionality corresponding to some already existing interface - which is what we're talking about here.
Any of these actions could result in "new bodies of code" being "injected" that "add add no functionality used/needed by" Boost.MPI (to choose "at random" one dependent of Boost.Serialization), and probably, they often do.
But that would of course that be a different case.
Don't you expect the author of type_traits to do the same thing?
No. I don't.
If I use something like "is_arithmetic" I expect it's functionality to not change in the future.
That's not at all like what you said happened. Sure you would expect is_arithmetic to remain the same.
What you said was that "new bodies of code" were "injected" that "add no functionality used/needed by Boost.Serialization."
well, boost::throw_exception(x) wraps the x in some other class with some other stuff and does a throw.
Right. That changes the type actually thrown, and that's a change of behavior someone slipped in, which is a totally different issue from the header dependency issue. The change of behavior in this case is almost certainly benign most of the time, since the exception actually thrown has a copy of x as a base subobject...but still, it's a substantial change of behavior, and it's entirely legitimate to complain if and when something like this happens behind your back (I'm not saying it did or didn't happen behind your back, though; I don't know the history well enough to judge).
The serialization library does't use this. In order do this, I has to include some headers from boost exception. I've labeled this "code injection". Maybe it should have been "dependcy extension" but not the less I don't think I've said anything misleading..
No, I don't think so either. I just think you fail to appreciate how easily, silently, and commonly header dependencies actually proliferate in Boost. These things happen *all the time*, and you never even notice.
We did that to type_traits when we upgraded it to work more smoothly with Boost.MPL. Changes like that are rare, but changes like this one aren't:
The maintainer of is_arithmetic makes changes to support compiler X. Boost.Serialization does not support compiler X. Therefore these changes "add no functionality used/needed by Boost.Serialization."
Such changes might be arbitrarily complicated, including pulling in new header files.
In this example the choice is clear. Either add suport for compiler X at the cost of increasing the code base or leave compiler X unsupported. And as the person responsable for the serialization library - I need to have the authority to make this decision. In this case the decision was made for me
The decision about change of behavior was made for you. Let's just keep that clearly distinguished from the library dependency issue, please.
and didn't really evaluate all the concequences.
Who didn't?
This is no surprise because changes like this have a much larger ripple effect that first meets the eye. This has been my principal objection from the begining.
Take the pottery barn rule:
"if you break it, you bought it"
this seems reasonable. Hence the following must be true:
"If you're not prepared to buy it, don't risk breaking it!"
So, unless one is prepared to take responsablity for the consequences, to muck with some other library.
Emil clearly was prepared to take responsibility for the consequences, and he did. He broke something (bad Emil!), and then he fixed it (good man!). What am I missing?
We have a plan that's less ad-hoc than the last one?
There are number of other libraries which have implemented the same work around that the serialization library has - presumably for similar motivations. Each of these has been specified in it's own namespace. We're considering consolidating these into one header in the boost namespace/directory to put all these work arounds in a single place. Basically this would give a new name to the original boost::throw() functionality.
I see. Doesn't handle the cultural rift, but it's cleaner architecturally than the status quo. I'm still concerned that we get this issue figured out though.
My guess so far is that you have something real in mind, but you're not expressing it with enough precision for others to grasp it. I think it might help if you could make an effort to be extremely concise, so your point is in a non-TL;DR context. If you use very few words it should be very obvious to you whether they'll communicate what you actually mean to say.
lol - could be. but it's not as easy as it looks.
Of course not. There are several famous quotations about how concision is harder than verbosity. But it is worth the effort. I work at it every time I write.
I'll try.
Thank you! I mean that sincerely. -- Dave Abrahams BoostPro Computing http://www.boostpro.com