
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases. To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate? Hot fixes might work something like this. (I'll use an embarrassing Boost.Filesystem mistake I made as an example.) * Individual developers will decide on a case-by-case basis if they want to provide a hot fix for a given bug. * There would be a prominent link on the web site to a "Hot Fixes" page in the trac. * That "Hot Fixes" page would have a section for each release. * Under release 1.36.0, there would be a changeset number, a description of the problem, and a directory-location: 48192 Restore deprecated basic_directory_entry names inadvertently removed. (boost/filesystem) * The changeset number would link to http://svn.boost.org/trac/boost/changeset/48192 * The "Hot Fixes" page would include instructions on how to apply a changeset. The instructions are the same for all operating systems: -- Click on "Download in other formats: Unified Diff". -- From the command prompt, cd directory-location patch <download-location/changeset_r48192.diff * The "Hot Fixes" page would include instructions on how to install "patch" for popular operating systems, and give an example of actual usage. Comments? --Beman

2008/8/18 Beman Dawes <bdawes@acm.org>:
* Under release 1.36.0, there would be a changeset number, a description of the problem, and a directory-location:
48192 Restore deprecated basic_directory_entry names inadvertently removed. (boost/filesystem)
* The changeset number would link to http://svn.boost.org/trac/boost/changeset/48192
We really should put the fixes on their own branch, called something like 'branches/fixes_1_36_0' or 'branches/fixes/1_36_0' (since we want to distinguish fixes from releases). This would be branched from release at the point of release (or maybe from the release tag). Daniel

Beman Dawes schrieb:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
As a user who has been hit by the filesystem problem: Actually, better no. Let me explain why: I've tried Boost 1.36 on a branch, to find exactly this kind of problem. Now I noticed that something has been broken, I have two (well, three) options: * I can back off updating to Boost 1.36, wait for 1.37 (at most 3 months), and then continue to use the deprecated functionality (no work on my side, just waiting) * Update my code now to the new API from Boost 1.36 (* Patch my copy of Boost. This is something I really want to avoid, and in a corporate environment, it's even more difficult to patch 3rd party libraries) If the release cycle is really predictable and every 3 months, I seriously doubt there will be any kind of bug that warrants a point release in between (with QA etc.). The only thing which would have helped me would be some documentation what has changed from 1.35->1.36 and how to update to 1.36 (i.e. changed APIs etc.). Known issues could be documented just like this, so if something got totally broken, users would have to wait at most 3 months to get it fixed. Cheers, Anteru

I think release-specific "hot fixes" could be useful. Perhaps, only changes preserving binary compatibility should qualify as hot fixes for a release. Also, I think only changes that are part of trunk code and, as such, are tested by the Boost regression testing should be allowed as hot fixes. Thanks, Boris
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Beman Dawes Sent: Monday, August 18, 2008 10:32 AM To: Boost Developers Mailing List Subject: [boost] Should we provide hot fixes?
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
Hot fixes might work something like this. (I'll use an embarrassing Boost.Filesystem mistake I made as an example.)
* Individual developers will decide on a case-by-case basis if they want to provide a hot fix for a given bug.
* There would be a prominent link on the web site to a "Hot Fixes" page in the trac.
* That "Hot Fixes" page would have a section for each release.
* Under release 1.36.0, there would be a changeset number, a description of the problem, and a directory-location:
48192 Restore deprecated basic_directory_entry names inadvertently removed. (boost/filesystem)
* The changeset number would link to http://svn.boost.org/trac/boost/changeset/48192
* The "Hot Fixes" page would include instructions on how to apply a changeset. The instructions are the same for all operating systems:
-- Click on "Download in other formats: Unified Diff". -- From the command prompt, cd directory-location patch <download-location/changeset_r48192.diff
* The "Hot Fixes" page would include instructions on how to install "patch" for popular operating systems, and give an example of actual usage.
Comments?
--Beman
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
NOOOOOOOOOOOOOOOO!!!! <deleted proposed procedure below> This create a whole new procedure. I think taking the current one to its logical conclusion will get you want you want with much less effort. Here is what I suggest. a) You make the fixes you want on your own machine, branch or whatever. b) Test them against the "current release ready" version. Right now that is the release branch which is currently at 1.36. This branch should be tagged via SVN to be named "1.36". c) Merge them into the trunk. d) Request permision from the release manager to merge them into the "current release ready", I this case I would expect that such permision would be granted without problem. e) Merge changes into the "current release ready". f) Wait for testing on "current release ready" branch to complete. At this point there are a couple of options a) Just inform users that the "hot fix" is in the "current release ready" branch an that he can either sync with this release with SVN or just patch his own system. b) Tag the "current release ready" branch as "1.36.1" c) Optionally create a new tarball and upload etc. Note that this last item presumes the release procedure is implemented as some sort of command like "BuildReleasePackage" <SVN tag> and that the release procedure is fully automated. Which in turn presumes that it is tested whenever something it depends upon changes. So the procedure should be part of boost/tools/with its own small test suite. Thus it could be tested and debugged on a small / simple dummy release with "BuildReleasePackage" dummy Robert Ramey

on Mon Aug 18 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
NOOOOOOOOOOOOOOOO!!!!
<deleted proposed procedure below>
<deleted proposed procedure below> Your procedure --- more so than even Beman's original proposal which has some of the same characteristic --- seems to ignore many users' need for traditional point releases that are identical to a previous release except for critical bugfixes. I probably shouldn't be complaining since it's to my benefit that people need Boostpro's enterprise support contract in order to get that kind of update. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Mon Aug 18 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
NOOOOOOOOOOOOOOOO!!!!
<deleted proposed procedure below>
<deleted proposed procedure below>
Your procedure --- more so than even Beman's original proposal which has some of the same characteristic --- seems to ignore many users' need for traditional point releases that are identical to a previous release except for critical bugfixes.
True
I probably shouldn't be complaining since it's to my benefit that people need Boostpro's enterprise support contract in order to get that kind of update.
This allocates the cost of providing such a service to those who require and benefit from it while simplifying the job of the release manager. This sounds like a good and fair solution to me. Robert Ramey

On Tue, Aug 19, 2008 at 8:11 AM, Robert Ramey <ramey@rrsd.com> wrote:
David Abrahams wrote:
Your procedure --- more so than even Beman's original proposal which has some of the same characteristic --- seems to ignore many users' need for traditional point releases that are identical to a previous release except for critical bugfixes.
True
I think this is unfortunate.
I probably shouldn't be complaining since it's to my benefit that people need Boostpro's enterprise support contract in order to get that kind of update.
This allocates the cost of providing such a service to those who require and benefit from it while simplifying the job of the release manager. This sounds like a good and fair solution to me.
This is assuming that there will only be one release manager for all the releases. I don't think this attitude of dismissing non-enterprise users of an open source product is really a healthy one especially for a project like Boost that has a huge following and plays a critical role in the further advancement of C++. Although I have no problems with BoostPro doing it for their customers, is it really that bad that the Boost developers would rather leave that up to someone else to address (which is providing bugfix releases)? -- Dean Michael C. Berris Software Engineer, Friendster, Inc.

On Mon, 18 Aug 2008, Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
Yes and no. Yes -- trivial bloopers shouldn't require a 3-month turnaround.
-- Click on "Download in other formats: Unified Diff". -- From the command prompt, cd directory-location patch <download-location/changeset_r48192.diff
No -- this is too complex. For any reasonably large project, instructions beyond "install version 1.36" are generally ignored. I've already had the fun of helping distribute in-house tarballs for boost, setting up my own tests, server, etc. so people wouldn't have to slurp 1.35+ from SVN. Much better would be if these "hotfixes" could be applied to the release (and trunk) branches, tested against the usual mechanisms, and released as a micro version number. Then everyone gets the update from the main boost servers. Of course this puts more work on the release manager's shoulders, so your opinion may differ. But these hotfixes should truly be trivial; thus testing should be easy, and it gives you more opportunities to test the release system. :) For anything nontrivial, I'd point people to the appropriate SVN branch. And nontrivial things generally motivate end-users to jump greater hurdles or just wait a few months. Another possibility would be to distribute a boost-hotfix.sh script along with boost releases. If it contained a hard-coded path to boost.org, then users could run boost-hotfix which would automatically download and apply any patches which had been uploaded properly. This script would look something like wget boost.org/1.36/hotfixes for fix in hotfixes do # only apply new fixes if test ! -f applied/$fix then wget $fix || exit 1 patch -p0 < $fix || exit 1 touch applied/$fix fi done - Daniel

dherring@ll.mit.edu wrote:
On Mon, 18 Aug 2008, Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
Yes and no. Yes -- trivial bloopers shouldn't require a 3-month turnaround.
-- Click on "Download in other formats: Unified Diff". -- From the command prompt, cd directory-location patch <download-location/changeset_r48192.diff
No -- this is too complex. For any reasonably large project, instructions beyond "install version 1.36" are generally ignored. I've already had the fun of helping distribute in-house tarballs for boost, setting up my own tests, server, etc. so people wouldn't have to slurp 1.35+ from SVN.
Much better would be if these "hotfixes" could be applied to the release (and trunk) branches, tested against the usual mechanisms, and released as a micro version number. Then everyone gets the update from the main boost servers.
Of course this puts more work on the release manager's shoulders,
And the testers, and those who admin the report servers, and those who review betas, etc. If all you want is updated release packages, you can always download the nightly snapshots. Of course, your milage may vary. --Beman

Beman Dawes wrote:
Much better would be if these "hotfixes" could be applied to the release (and trunk) branches, tested against the usual mechanisms, and released as a micro version number. Then everyone gets the update from the main boost servers.
Of course this puts more work on the release manager's shoulders,
And the testers, and those who admin the report servers, and those who review betas, etc.
If all you want is updated release packages, you can always download the nightly snapshots. Of course, your milage may vary.
Nightly snapshots of what? In the current scheme there's no branch where hotfixes for 1.36 are supposed to be applied. Neither trunk nor release branches are obviously not good for that since they get big changes. Besides, do we have nightly snapshots of any branch? I don't see any links on boost.org. - Volodya

Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
I'm not really up to speed on the release process, but it seems to me getting a point release out should be significantly easier than a major release. What's the real difference between what you've outlined below and providing a point release? We'd still need to branch off the release, and we'd still need to run tests to make sure no broken fixes go out, don't we? -- Daniel Wallin BoostPro Computing http://www.boostpro.com

Daniel Wallin wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
I'm not really up to speed on the release process, but it seems to me getting a point release out should be significantly easier than a major release. What's the real difference between what you've outlined below and providing a point release? We'd still need to branch off the release, and we'd still need to run tests to make sure no broken fixes go out, don't we?
I believe test resources are the bottleneck here. Sebastian

Sebastian Redl wrote:
Daniel Wallin wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
I'm not really up to speed on the release process, but it seems to me getting a point release out should be significantly easier than a major release. What's the real difference between what you've outlined below and providing a point release? We'd still need to branch off the release, and we'd still need to run tests to make sure no broken fixes go out, don't we?
I believe test resources are the bottleneck here.
It that's the case then that problem won't go away by releasing patches rather than point releases; they still need testing. -- Daniel Wallin BoostPro Computing http://www.boostpro.com

Daniel Wallin wrote:
Sebastian Redl wrote:
Daniel Wallin wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
I'm not really up to speed on the release process, but it seems to me getting a point release out should be significantly easier than a major release. What's the real difference between what you've outlined below and providing a point release? We'd still need to branch off the release, and we'd still need to run tests to make sure no broken fixes go out, don't we?
I believe test resources are the bottleneck here.
Yes.
It that's the case then that problem won't go away by releasing patches rather than point releases; they still need testing.
But the patch testing occurs on trunk and branches/release. We are already testing those, so no additional testing, reporting, or admin effort is required. --Beman

Beman Dawes skrev:
Daniel Wallin wrote:
It that's the case then that problem won't go away by releasing patches rather than point releases; they still need testing.
But the patch testing occurs on trunk and branches/release. We are already testing those, so no additional testing, reporting, or admin effort is required.
If regression testing is already being performed on both trunk and branches/release, I don't see why you would not want to do something like what I proposed here: http://thread.gmane.org/gmane.comp.lib.boost.devel/178864/focus=178958 Back then the reason for not doing it this way was testing obstacles, but if both trunk *and* a release branch are tested, I don't see the problem. It is just a matter of switching which release branch is tested once for each major release. I.e. now testing should be performed on trunk and releases/boost_1_36. For the next major release it would be trunk and branches/boost_1_37. If the release process can be made more automated (preferably nearly fully automatic), all the features that people ask regarding the release process will come nearly for free (without extra burden for either developers or release managers). That is you are able to keep a stable, *tested* interface on the release branch (e.g. branches/boost_1_36), while providing hotfixes there (see my other post), and you can easily create point releases by at some point in time ensuring that test results are acceptable on the release branch, tagging it, and creating a release package. At the same time normal development and adding new features or interface breaking changes is going on in trunk, which is also tested all the time. For the next major release, you would just create a new branch, branches/boost_1_37, from trunk, and switch testing to that new release branch. Also note that users wishing to keep up to date with all bugfixes, but still wanting a stable interface, would just have to checkout and update the current release branch, e.g. branches/boost_1_36. Best regards, Christian

Christian Larsen skrev: [SNIP]
I.e. now testing should be performed on trunk and releases/boost_1_36. For the next major release it would be trunk and branches/boost_1_37. That should of course have been branches/boost_1_36...
Btw, regarding the argument that some developers don't want to maintain multiple branches, there's no problem. They can keep developing on trunk as always and their changes will automatically make into the next major release, when that is branched off from trunk. --Christian

on Mon Aug 25 2008, Christian Larsen <contact-AT-dword.dk> wrote:
Christian Larsen skrev: [SNIP]
I.e. now testing should be performed on trunk and releases/boost_1_36. For the next major release it would be trunk and branches/boost_1_37. That should of course have been branches/boost_1_36...
Btw, regarding the argument that some developers don't want to maintain multiple branches, there's no problem. They can keep developing on trunk as always and their changes will automatically make into the next major release, when that is branched off from trunk.
It's been a major bone of contention here recently, but releases are not branched from trunk. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams skrev:
on Mon Aug 25 2008, Christian Larsen <contact-AT-dword.dk> wrote:
Christian Larsen skrev: Btw, regarding the argument that some developers don't want to maintain multiple branches, there's no problem. They can keep developing on trunk as always and their changes will automatically make into the next major release, when that is branched off from trunk.
It's been a major bone of contention here recently, but releases are not branched from trunk.
That may be the case, and please excuse my ignorance, but I was referring to how it would be done if the process I suggested was used. Best regards, Christian

Christian Larsen wrote:
Christian Larsen skrev: [SNIP]
I.e. now testing should be performed on trunk and releases/boost_1_36. For the next major release it would be trunk and branches/boost_1_37. That should of course have been branches/boost_1_36...
Btw, regarding the argument that some developers don't want to maintain multiple branches, there's no problem. They can keep developing on trunk as always and their changes will automatically make into the next major release, when that is branched off from trunk.
Lets make it even simpler: Maintain ONE branch called "ReleaseReady" Make 1.36 is just a tag ("copy" in SVN parlance) on this branch. So all I have to do is have ONE branch on my machine: "Release Ready" and I'm automatically upto date with all the latest - TESTED - changes which have been merged into ReleaseReady. Even better, I can switch my local copy of the serialization library to trunk and and run all my local tests agains the "Release Ready" branch and know (almost) that my stuff is compatible with the current release ready version. This will always be the case no matter how many other branches 1.36.1, or whatever are made. Robert Ramey

Robert Ramey skrev:
Christian Larsen wrote:
Christian Larsen skrev: [SNIP]
I.e. now testing should be performed on trunk and releases/boost_1_36. For the next major release it would be trunk and branches/boost_1_37. That should of course have been branches/boost_1_36...
Btw, regarding the argument that some developers don't want to maintain multiple branches, there's no problem. They can keep developing on trunk as always and their changes will automatically make into the next major release, when that is branched off from trunk.
Lets make it even simpler:
Maintain ONE branch called "ReleaseReady"
I didn't mean to offend anyone, sorry if I did.
Make 1.36 is just a tag ("copy" in SVN parlance) on this branch.
So all I have to do is have ONE branch on my machine: "Release Ready" and I'm automatically upto date with all the latest - TESTED - changes which have been merged into ReleaseReady.
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady". Many users would appreciate bugfix-only releases, because they may not be able to/have the time or money/whatever reason to update to a new interface that often. Anyway, I'm in no position to change anything; I just wanted to share my point of view on how things could be done resulting in what many people would like: point releases with a stable interface and bugfixes, at little cost for developers and release managers. I'll rest my case. Best regards, Christian

Christian Larsen wrote:
Robert Ramey skrev:
Make 1.36 is just a tag ("copy" in SVN parlance) on this branch.
So all I have to do is have ONE branch on my machine: "Release Ready" and I'm automatically upto date with all the latest - TESTED - changes which have been merged into ReleaseReady.
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
You're correct that this depends upon developers not merging interface breaking changes into "ReleaseReady" We recently had a discussion about just this topic. I expressed the position that such interface breaking changes should be considered bugs. I also pledged to personally consider such changes in the serialization library as bugs and treat them as such. Much to my amazement, the idea that all boost developers should adhere to such a position was considered by some to be a bad idea. To me it is the bedrock of serious, quality software. If everyone adhered to this, we would have a lot fewer problems.
Many users would appreciate bugfix-only releases, because they may not be able to/have the time or money/whatever reason to update to a new interface that often.
When I find that a library author changes the interface - and I have to go back to change my code, the whole justification for using the library in the first place goes out the window. I either save the original copy of the library, or use another library with a stable interface. I don't have time to chase after everyone elses vision of perfection.
Anyway, I'm in no position to change anything; I just wanted to share my point of view
LOL - well that's all I do.
on how things could be done resulting in what many people would like: point releases with a stable interface and bugfixes, at little cost for developers and release managers.
I would make a distinction between an interface change and a bug fix which just changes the implemention. The former should never occur. And if it does it shouldn't be in a point release or hot fix. Its a major change which should result in updated docs, release notes, tests, etc. Only the later is appropriate for point release, hot fix or whatever.
I'll rest my case.
LOL - me too - until its brought up again! Robert Ramey

Robert Ramey skrev:
Christian Larsen wrote: [SNIP]
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
You're correct that this depends upon developers not merging interface breaking changes into "ReleaseReady"
We recently had a discussion about just this topic. I expressed the position that such interface breaking changes should be considered bugs. I also pledged to personally consider such changes in the serialization library as bugs and treat them as such. Much to my amazement, the idea that all boost developers should adhere to such a position was considered by some to be a bad idea. To me it is the bedrock of serious, quality software.
I completely agree, and that's also how I like to think of Boost, as serious, quality software. Not having a stable interface gives the impression that Boost is "hobby" development only, and can't be used for serious purposes. But that's really a shame, as I consider the Boost developers as some of the best in the world! I'm starting to think that what is referred to as hotfixes in this thread is actually just patches lifting the released version up to the improved level of the "ReleaseReady" branch for specific libraries. And that being the case, I must say I like the idea of providing hotfixes. In that case it's basically what I was hoping to see, just that getting a fresh checkout from SVN might be easier than applying a lot of patches manually. Now I can have the option of doing it either way. :)
Christian Larsen wrote:
Many users would appreciate bugfix-only releases, because they may not be able to/have the time or money/whatever reason to update to a new interface that often.
When I find that a library author changes the interface - and I have to go back to change my code, the whole justification for using the library in the first place goes out the window. I either save the original copy of the library, or use another library with a stable interface. I don't have time to chase after everyone elses vision of perfection.
Exactly. At my work place we're still using version 1.33.1 (!) of Boost for this very reason.
Christian Larsen wrote:
on how things could be done resulting in what many people would like: point releases with a stable interface and bugfixes, at little cost for developers and release managers.
I would make a distinction between an interface change and a bug fix which just changes the implemention. The former should never occur. And if it does it shouldn't be in a point release or hot fix. Its a major change which should result in updated docs, release notes, tests, etc. Only the later is appropriate for point release, hot fix or whatever.
That's what I meant. In fact I think we're pretty much in agreement on this now. Especially after Beman Dawes explained the reasoning behind the current release process to me in the other thread... Best regards, Christian

At 7:19 PM +0200 8/26/08, Christian Larsen wrote:
Robert Ramey skrev:
Christian Larsen wrote: [SNIP]
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
You're correct that this depends upon developers not merging interface breaking changes into "ReleaseReady"
We recently had a discussion about just this topic. I expressed the position that such interface breaking changes should be considered bugs. I also pledged to personally consider such changes in the serialization library as bugs and treat them as such. Much to my amazement, the idea that all boost developers should adhere to such a position was considered by some to be a bad idea. To me it is the bedrock of serious, quality software.
I completely agree, and that's also how I like to think of Boost, as serious, quality software. Not having a stable interface gives the impression that Boost is "hobby" development only, and can't be used for serious purposes. But that's really a shame, as I consider the Boost developers as some of the best in the world!
I disagree. Changing interfaces, to me, implies that the developer: * Discovered a better way to solve the problem that he faced. * Decided that the benefits of the change outweighed the costs. The "don't change interfaces, ever, no matter what" is why we still have "strcpy" and "mktmp", to name just two examples. Bad interfaces are bugs; they should be fixed. Software does not spring full-blown from someone's forehead; it is a process of discovery and refinement. Interfaces follow that same path. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> Hey! Who messed with my anti-paranoia shot?

Marshall Clow skrev:
At 7:19 PM +0200 8/26/08, Christian Larsen wrote:
I completely agree, and that's also how I like to think of Boost, as serious, quality software. Not having a stable interface gives the impression that Boost is "hobby" development only, and can't be used for serious purposes. But that's really a shame, as I consider the Boost developers as some of the best in the world!
I disagree.
Changing interfaces, to me, implies that the developer: * Discovered a better way to solve the problem that he faced. * Decided that the benefits of the change outweighed the costs.
The "don't change interfaces, ever, no matter what" is why we still have "strcpy" and "mktmp", to name just two examples. Bad interfaces are bugs; they should be fixed.
No, no, please don't get me wrong. I'm not against changing interfaces in general, of course that's by all means the way to go if a better way is discovered. What I was trying to say is just, that for some uses it is nice to have a stable interface to stick to for a period until you decide yourself that have the time to upgrade to a new, and improved interface. Thus proving both options would be optimal, from a user's point of view. Of course developers should improve interfaces all the time, but it is impossible for them to "decide" whether the benefits of the change outweigh the cost, because for some users the cost might be high. Thus, from a user's point of view, the optimal approach is having both versions to choose from: a "bleeding edge" version including all improvements, and a "stable" version that you can use for a while until you decide yourself to upgrade to the new interfaces. Best regards, Christian

At 10:38 PM +0200 8/26/08, Christian Larsen wrote:
Marshall Clow skrev:
At 7:19 PM +0200 8/26/08, Christian Larsen wrote:
I completely agree, and that's also how I like to think of Boost, as serious, quality software. Not having a stable interface gives the impression that Boost is "hobby" development only, and can't be used for serious purposes. But that's really a shame, as I consider the Boost developers as some of the best in the world!
I disagree.
Changing interfaces, to me, implies that the developer: * Discovered a better way to solve the problem that he faced. * Decided that the benefits of the change outweighed the costs.
The "don't change interfaces, ever, no matter what" is why we still have "strcpy" and "mktmp", to name just two examples. Bad interfaces are bugs; they should be fixed.
No, no, please don't get me wrong. I'm not against changing interfaces in general, of course that's by all means the way to go if a better way is discovered. What I was trying to say is just, that for some uses it is nice to have a stable interface to stick to for a period until you decide yourself that have the time to upgrade to a new, and improved interface. Thus proving both options would be optimal, from a user's point of view.
But that way lies madness :-( Basically, you can never remove an interface, because someone, somewhere might be using it.
Of course developers should improve interfaces all the time, but it is impossible for them to "decide" whether the benefits of the change outweigh the cost, because for some users the cost might be high.
I disagree (again). The authors of the libraries are the only people who can decide when to change the interface. Other people can advise, and the authors should listen to them, but eventually, they decide (just like they decided upon the interface in the first place)
Thus, from a user's point of view, the optimal approach is having both versions to choose from: a "bleeding edge" version including all improvements, and a "stable" version that you can use for a while until you decide yourself to upgrade to the new interfaces.
Oh, is that what you're looking for? Boost already has that! The "stable versions" even have names: 1.34, 1.35, 1.36 (etc). As long as you use 1.34 (for example), the interfaces are guaranteed not to change. :-D -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

Marshall Clow skrev:
At 10:38 PM +0200 8/26/08, Christian Larsen wrote:
No, no, please don't get me wrong. I'm not against changing interfaces in general, of course that's by all means the way to go if a better way is discovered. What I was trying to say is just, that for some uses it is nice to have a stable interface to stick to for a period until you decide yourself that have the time to upgrade to a new, and improved interface. Thus proving both options would be optimal, from a user's point of view.
But that way lies madness :-( Basically, you can never remove an interface, because someone, somewhere might be using it.
Never to remove interfaces is not what I'm trying to advocate either. ;) Just to provide bugfixes for a stable interface for some period (like the major release cycle), so that people can adjust over time, and decide themselves exactly when in that period they have the resources to do a full upgrade. Once the next major release is out, you are free to "rm -rf" the old release branch, I couldn't care less. We all know that no software is perfect, although some gets close, so it may be too long to wait for next major release to get bugfixes. What you say is that for instance, if a nasty bug was discovered in shared_ptr (which is highly unlikely, I know) some time after a release, people should just immediately jump to the newest "ReleaseReady" no matter what other (possibly interface breaking) changes have been made to Boost as a whole. Then they'd have to port all their existing code to conform to all changed interfaces at that point in time, because the developers decided that the time was right? And that is just to get a single bugfix. It could require a whole lot of work, reading changelogs, and documentation etc.
Of course developers should improve interfaces all the time, but it is impossible for them to "decide" whether the benefits of the change outweigh the cost, because for some users the cost might be high.
I disagree (again). The authors of the libraries are the only people who can decide when to change the interface.
Of course they decide when to change the interface, but they can never decide when that change can be followed up on by users of the libraries. Not all users are able to throw away whatever they are currently doing, to sit and update their codebase to new interfaces, whenever they would like to have a bugfix. Which is why I think interface breaking changes should be insulated from a release branch in the first place... [SNIP]
Thus, from a user's point of view, the optimal approach is having both versions to choose from: a "bleeding edge" version including all improvements, and a "stable" version that you can use for a while until you decide yourself to upgrade to the new interfaces.
Oh, is that what you're looking for? Boost already has that! The "stable versions" even have names: 1.34, 1.35, 1.36 (etc). As long as you use 1.34 (for example), the interfaces are guaranteed not to change. :-D
Yes of course, but also from following the list, there has already been discovered bugs in the newest release, which is why people are discussing whether to provide hotfixes. ;) As I see it there currently is no way of ensuring that users can benefit from bugfixes while still relying on a stable interface. It's either all or nothing. Best regards, Christian

Marshall Clow wrote:
At 10:38 PM +0200 8/26/08, Christian Larsen wrote:
Basically, you can never remove an interface, because someone, somewhere might be using it.
That's basically correct - that's why in general you should only extend an interface or make a new interface. To do otherwise breaks faith with the users of your library. No problem if you want to create a new interface - just give it a new name. Robert Ramey

2008/8/26 Robert Ramey <ramey@rrsd.com>:
That's basically correct - that's why in general you should only extend an interface or make a new interface. To do otherwise breaks faith with the users of your library.
No problem if you want to create a new interface - just give it a new name.
I've got a library based on the draft standard. And the interface in the draft standard changed. So I changed the interface. Creating a new name would be ridiculous. Daniel

Daniel James wrote:
2008/8/26 Robert Ramey <ramey@rrsd.com>:
That's basically correct - that's why in general you should only extend an interface or make a new interface. To do otherwise breaks faith with the users of your library.
No problem if you want to create a new interface - just give it a new name.
I've got a library based on the draft standard. And the interface in the draft standard changed. So I changed the interface. Creating a new name would be ridiculous.
This discussion doesn't apply to a "draft standard" since the name itself indicates that the interface isn't stable. In any case, you didn't change the interface - the writer of the "draft standard" did, this wouldn't have anyting to do with you. even the phrase "draft standard" standard seems like an oxymoron to me. I'm presuming it means something like "proposed standard". Robert Ramey
Daniel _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

2008/8/27 Robert Ramey <ramey@rrsd.com>:
even the phrase "draft standard" standard seems like an oxymoron to me. I'm presuming it means something like "proposed standard".
The full title is: 'Working Draft, Standard for Programming Language C++'. I think 'draft standard' is a reasonable abbreviation. Obviously, I'm relying on the context. I suppose something like 'the C++0x draft' might be clearer and still brief. Daniel

on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Marshall Clow wrote:
At 10:38 PM +0200 8/26/08, Christian Larsen wrote:
Basically, you can never remove an interface, because someone, somewhere might be using it.
That's basically correct - that's why in general you should only extend an interface or make a new interface. To do otherwise breaks faith with the users of your library.
No problem if you want to create a new interface - just give it a new name.
1. I agree with Marshall. Code rots and dies and is eventually replaced, and that's a good thing. The question is how to manage that process responsibly. I'll say again, with at most one or two exceptions, Boost library authors have been very responsible to their users in making changes to the libraries. 2. Robert, you're sounding a lot less flexible about this than you ended up being in this thread: http://news.gmane.org/find-root.php?message_id=%3cg5li1k%24tbl%241%40ger.gma... Have you forgotten about the issues that caused you to admit there might be good reasons for interface-breaking changes? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
2. Robert, you're sounding a lot less flexible about this than you ended up being in this thread:
I've that in some cases its unavoidable. My problem is really the idea that breaking an interface is OK and normal. With a library in wide use, this creates a lot of new work for hundreds, thousands, tens of thousands? of people and prevents or delays users from upgrading until they can find time to put in that effort. Developers who engage in this practice will find that they lose users. To obsolete all the code that uses a library is a very costly decision which I believe developers don't take seriously enough. I drive an 11 year old Ford Taurus. I just had new spark plugs put in it. Imagine how I would feel if I was told - we don't make spark plugs for that model any more. The new design is much, much better. What do I do - replace the engine? Of course pollution laws could change and I might be required purchase some expensive upgrade - as I said, sometimes and interface change is unavoidable - but it is still costly and only to be take as a last resort. I understand that we want to make our works of art perfect. And its really, really annoying to live with a mistake knowing that we could have done better. But its self indulgent not to consider the impact of those who are counting on you to deliver the benefits of using your library. I'm sure that lots of projects are stuck with boost 1.33 because of this problem and I think that's a shame. And the most annoying thing is that many times its not really necessary. A new name could be created. Not as aesthetically pleasing perhaps, but still very effective. So, I think this is done more often than is really necessary because the impact of doing so is not sufficiently appreciated. Robert Ramey

on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
2. Robert, you're sounding a lot less flexible about this than you ended up being in this thread:
I've that in some cases its unavoidable.
Huh?
My problem is really the idea that breaking an interface is OK and normal. With a library in wide use, this creates a lot of new work for hundreds, thousands, tens of thousands? of people and prevents or delays users from upgrading until they can find time to put in that effort. Developers who engage in this practice will find that they lose users. To obsolete all the code that uses a library is a very costly decision which I believe developers don't take seriously enough.
Yeah, but my point is that with very few exceptions, you're preaching to the choir by making your case here, and you're not giving your fellow Boost developers enough credit. If you know of cases where people broke backward compatibility in ways that were irresponsible, it would be good to hear about those. And it wouldn't hurt for Boost to have a guidelines page on how to manage interface evolution. I might just write one.
I drive an 11 year old Ford Taurus. I just had new spark plugs put in it. Imagine how I would feel if I was told - we don't make spark plugs for that model any more. The new design is much, much better. What do I do - replace the engine?
That's a false analogy. If you tried to upgrade the engine and you were told "the new engine isn't a drop-in replacement for the old one; you'll need $2000 in additional parts and labor just to get it hooked up" it would be much more apt.
From my point-of-view, it seems reasonable. Car makers don't preserve backward compatibility every time they come out with a new part. Can you imagine if Ford felt constrained to make all the parts in your Taurus work in a model T?
I understand that we want to make our works of art perfect. And its really, really annoying to live with a mistake knowing that we could have done better. But its self indulgent not to consider the impact of those who are counting on you to deliver the benefits of using your library. I'm sure that lots of projects are stuck with boost 1.33 because of this problem and I think that's a shame.
And the most annoying thing is that many times its not really necessary. A new name could be created. Not as aesthetically pleasing perhaps, but still very effective.
So, I think this is done more often than is really necessary
By whom? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
If you know of cases where people broke backward compatibility in ways that were irresponsible, it would be good to hear about those. And it wouldn't hurt for Boost to have a guidelines page on how to manage interface evolution. I might just write one.
I'm referring specificly to the episode regarding boost exception where by the purpose of boost::throw exception was changed from a limited, lightweight piece of code crafted to address the simple problem that some compilers don't implement "throw" to a heavy weight (includes a bunch of new headers) module whose purpose is totally inpenetrable and adds RTTI requirement to any library which used boost::throw exception. The most gauling was that when i pointed this out, no one seemed to see this as a problem. In fact, there was no acknowedgement that this was even an error. and no promise to fix it. I got the feeling that the author thought this to be perfectly legitimate given the new superior features (which are required by current users) and that I should plan for future episodes of this nature. Which is what I've done by removing dependence on boost/throw_exception.hpp so its now and in the future a non-problem for me. I have done something similar at least one time in the past. Robert Ramey

Quoting Robert Ramey <ramey@rrsd.com>:
[Boost.Exception] In fact, there was no acknowedgement that this was even an error. and no promise to fix it. I got the feeling that the author thought this to be perfectly legitimate given the new superior features (which are required by current users) and that I should plan for future episodes of this nature.
What Emil actually wrote was: Robert Ramey wrote:
Emil Dotchevski wrote:
The semantics of boost::throw_exception have not changed.
That's where we differ. It seems to me that on certain platforms things won't work as they had before.
If that's true, it's a bug and I'll fix it.
Emil Dotchevski
(http://article.gmane.org/gmane.comp.lib.boost.devel/178970)

on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
If you know of cases where people broke backward compatibility in ways that were irresponsible, it would be good to hear about those. And it wouldn't hurt for Boost to have a guidelines page on how to manage interface evolution. I might just write one.
I'm referring specificly to the episode regarding boost exception where by the purpose of boost::throw exception was changed from a limited, lightweight piece of code crafted to address the simple problem that some compilers don't implement "throw" to a heavy weight (includes a bunch of new headers) module whose purpose is totally inpenetrable and adds RTTI requirement to any library which used boost::throw exception.
This does look like a problem to me. Hmm, I can't find any discussion on the list in which Peter Dimov, who was the author of throw_exception, participated. Did Emil get Peter's approval for this change? http://www.boost.org/doc/libs/1_36_0/libs/utility/throw_exception.html still seems to imply that the implementation is as lightweight as ever, and nowhere does it state that there are any constraints on the type of the exception being thrown, although as Emil points out in http://article.gmane.org/gmane.comp.lib.boost.devel/177620 they were always there (discoverable by #defining BOOST_NO_EXCEPTIONS).
The most gauling was that when i pointed this out, no one seemed to see this as a problem.
Maybe the right people weren't reading your post.
In fact, there was no acknowedgement that this was even an error. and no promise to fix it. I got the feeling that the author thought this to be perfectly legitimate given the new superior features (which are required by current users) and that I should plan for future episodes of this nature.
Well, I really hope I'm missing something, but from the evidence I see before me, this was at least not handled well. We have a Boost-wide convention that libraries wanting to report errors on compilers with no exceptions support use boost::throw_exception. The change of boost::throw_exception essentially made a Boost-wide policy decision that such libraries, when they *do* throw, will integrate the Boost.Exception machinery. That shouldn't have happened without a broader discussion. It's also a bit strange because it seems to me that the libraries that want to be able to work with exceptions off are somehow less likely to be interested in the functionality of Boost.Exception than the others, and many of the other libraries still contain raw "throw" clauses.
Which is what I've done by removing dependence on boost/throw_exception.hpp so its now and in the future a non-problem for me. I have done something similar at least one time in the past.
I'd like to know more. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Wed, Aug 27, 2008 at 3:13 PM, David Abrahams <dave@boostpro.com> wrote:
on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
[snip]
The most gauling was that when i pointed this out, no one seemed to see this as a problem.
Maybe the right people weren't reading your post.
In fact, there was no acknowedgement that this was even an error. and no promise to fix it. I got the feeling that the author thought this to be perfectly legitimate given the new superior features (which are required by current users) and that I should plan for future episodes of this nature.
Well, I really hope I'm missing something, but from the evidence I see before me, this was at least not handled well. We have a Boost-wide convention that libraries wanting to report errors on compilers with no exceptions support use boost::throw_exception. The change of boost::throw_exception essentially made a Boost-wide policy decision that such libraries, when they *do* throw, will integrate the Boost.Exception machinery. That shouldn't have happened without a broader discussion.
AFAIK, the boost was never meant to be used without RTTI without defining BOOST_NO_RTTI. So that I don't see how Boost.Exception is violating boost::throw_exception requirements. AFAIU, boost::throw_exception disables (if it doesn't, then I would call it a bug) boost.exception use when defining BOOST_NO_RTTI. This didn't seem to have been discussed enough in that thread, and most of what was said is that something worked when no RTTI was available and that it doesn't work anymore. [snip]
I'd like to know more.
-- Dave Abrahams BoostPro Computing http://www.boostpro.com
-- Felipe Magno de Almeida

on Wed Aug 27 2008, "Felipe Magno de Almeida" <felipe.m.almeida-AT-gmail.com> wrote:
On Wed, Aug 27, 2008 at 3:13 PM, David Abrahams <dave@boostpro.com> wrote:
on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
[snip]
The most gauling was that when i pointed this out, no one seemed to see this as a problem.
Maybe the right people weren't reading your post.
In fact, there was no acknowedgement that this was even an error. and no promise to fix it. I got the feeling that the author thought this to be perfectly legitimate given the new superior features (which are required by current users) and that I should plan for future episodes of this nature.
Well, I really hope I'm missing something, but from the evidence I see before me, this was at least not handled well. We have a Boost-wide convention that libraries wanting to report errors on compilers with no exceptions support use boost::throw_exception. The change of boost::throw_exception essentially made a Boost-wide policy decision that such libraries, when they *do* throw, will integrate the Boost.Exception machinery. That shouldn't have happened without a broader discussion.
AFAIK, the boost was never meant to be used without RTTI without defining BOOST_NO_RTTI. So that I don't see how Boost.Exception is violating boost::throw_exception requirements. AFAIU, boost::throw_exception disables (if it doesn't, then I would call it a bug) boost.exception use when defining BOOST_NO_RTTI.
Yes, that's what it seems to do. I had looked in the wrong place (Boost.Exception's own headers) for mentions of BOOST_NO_RTTI and didn't see any. It doesn't change my overall point, though. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams:
on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
If you know of cases where people broke backward compatibility in ways that were irresponsible, it would be good to hear about those. And it wouldn't hurt for Boost to have a guidelines page on how to manage interface evolution. I might just write one.
I'm referring specificly to the episode regarding boost exception where by the purpose of boost::throw exception was changed from a limited, lightweight piece of code crafted to address the simple problem that some compilers don't implement "throw" to a heavy weight (includes a bunch of new headers) module whose purpose is totally inpenetrable and adds RTTI requirement to any library which used boost::throw exception.
This does look like a problem to me.
Hmm, I can't find any discussion on the list in which Peter Dimov, who was the author of throw_exception, participated. Did Emil get Peter's approval for this change?
Yes, I did approve this change. Do note that the problem with throw_exception now requiring RTTI was not pointed out by anyone prior to release, and it was some of our users who discovered it, after 1.36 has been finalized. As a response to this issue, I requested a new macro, BOOST_NO_RTTI, be added to Boost.Config, and John has kindly done that. I expect Emil to modify Boost.Exception to honor BOOST_NO_RTTI as soon as possible. Since we are now officially not doing point releases, the earlier this can be fixed is in 1.37, so it is not fair to accuse Emil of being unresponsive about it. (Hotfixes notwithstanding.)
Well, I really hope I'm missing something, but from the evidence I see before me, this was at least not handled well. We have a Boost-wide convention that libraries wanting to report errors on compilers with no exceptions support use boost::throw_exception. The change of boost::throw_exception essentially made a Boost-wide policy decision that such libraries, when they *do* throw, will integrate the Boost.Exception machinery. That shouldn't have happened without a broader discussion.
So why didn't people discuss it then? http://lists.boost.org/Archives/boost/2008/02/133425.php "Let's discuss this issue before I submit the Boost Exception source code to SVN." http://lists.boost.org/Archives/boost/2008/04/136828.php

on Wed Aug 27 2008, "Peter Dimov" <pdimov-AT-pdimov.com> wrote:
David Abrahams:
on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
If you know of cases where people broke backward compatibility in ways that were irresponsible, it would be good to hear about those. And it wouldn't hurt for Boost to have a guidelines page on how to manage interface evolution. I might just write one.
I'm referring specificly to the episode regarding boost exception where by the purpose of boost::throw exception was changed from a limited, lightweight piece of code crafted to address the simple problem that some compilers don't implement "throw" to a heavy weight (includes a bunch of new headers) module whose purpose is totally inpenetrable and adds RTTI requirement to any library which used boost::throw exception.
This does look like a problem to me.
Hmm, I can't find any discussion on the list in which Peter Dimov, who was the author of throw_exception, participated. Did Emil get Peter's approval for this change?
Yes, I did approve this change.
In private only? I ask because I would have been interested in reading your rationale about it.
Do note that the problem with throw_exception now requiring RTTI was not pointed out by anyone prior to release, and it was some of our users who discovered it, after 1.36 has been finalized.
As a response to this issue, I requested a new macro, BOOST_NO_RTTI, be added to Boost.Config, and John has kindly done that. I expect Emil to modify Boost.Exception to honor BOOST_NO_RTTI as soon as possible.
So IIUC, your intention was never to require RTTI in throw_exception, and Emil didn't know that, so he violated your original intent unwittingly. What about the "weight" of the header and its dependencies? Your usual stance is to avoid such things. If we want throw_exception to work when there's no RTTI, we should try to somehow test it. We could do that by adding <cxxflags> for known popular compilers to turn it off for one test.
Since we are now officially not doing point releases, the earlier this can be fixed is in 1.37, so it is not fair to accuse Emil of being unresponsive about it. (Hotfixes notwithstanding.)
Well, I really hope I'm missing something, but from the evidence I see before me, this was at least not handled well. We have a Boost-wide convention that libraries wanting to report errors on compilers with no exceptions support use boost::throw_exception. The change of boost::throw_exception essentially made a Boost-wide policy decision that such libraries, when they *do* throw, will integrate the Boost.Exception machinery. That shouldn't have happened without a broader discussion.
So why didn't people discuss it then?
http://lists.boost.org/Archives/boost/2008/02/133425.php
"Let's discuss this issue before I submit the Boost Exception source code to SVN."
I can only speak for myself, but neither message's subject line alerted me to the fact that the change would represent a Boost-wide change of policy. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams:
So IIUC, your intention was never to require RTTI in throw_exception, ...
The new throw_exception was not supposed to impose any new requirements and it certainly was not supposed to break code that worked before. (It almost succeeded at that.)
and Emil didn't know that, so he violated your original intent unwittingly. What about the "weight" of the header and its dependencies? Your usual stance is to avoid such things.
Well, one upside is that exceptions thrown by boost::throw_exception now can be used with boost::exception_ptr. This makes exception_ptr more useful and requires zero effort from library authors who already throw all their exceptions via boost::throw_exception. The alternative way to provide such functionality would've been through a separate throw replacement, part of Boost.Exception. This would indeed have had zero impact on the rest of Boost, both in the negative and the positive sense. (That is, it would have required every library author willing to support exception_ptr to switch from boost::throw_exception to the new function.) It was impossible to predict in advance whether going with option A would be worth the trouble. The only way to find out was to try. I think that (for such a major change) the transition went fairly smoothly. We still have the option to revert throw_exception if the "broad discussion" that should have happened then but is happening now reaches this conclusion. Either way, we'll still be ahead of where we were, both because we now have BOOST_NO_RTTI and some awareness of its significance, and because the new throw_exception caught a few bugs.

on Wed Aug 27 2008, "Peter Dimov" <pdimov-AT-pdimov.com> wrote:
David Abrahams:
So IIUC, your intention was never to require RTTI in throw_exception, ...
The new throw_exception was not supposed to impose any new requirements and it certainly was not supposed to break code that worked before. (It almost succeeded at that.)
and Emil didn't know that, so he violated your original intent unwittingly. What about the "weight" of the header and its dependencies? Your usual stance is to avoid such things.
Well, one upside is that exceptions thrown by boost::throw_exception now can be used with boost::exception_ptr. This makes exception_ptr more useful and requires zero effort from library authors who already throw all their exceptions via boost::throw_exception.
I understand the benefits. You've completely avoided my question ;-) What about the "weight" of the header? Did imposing it on clients of boost::throw_exception concern you at all? If you went through some cost/benefit analysis (even in your own mind) I'd like to hear about it.
The alternative way to provide such functionality would've been through a separate throw replacement, part of Boost.Exception. This would indeed have had zero impact on the rest of Boost, both in the negative and the positive sense. (That is, it would have required every library author willing to support exception_ptr to switch from boost::throw_exception to the new function.)
Yes, I understand that too.
It was impossible to predict in advance whether going with option A would be worth the trouble. The only way to find out was to try.
Surely there must be another way to find out if library authors would react badly to a dependency on Boost.Exception. In fact, it might well have been possible to sell everyone on the idea before the fact, but it will be a lot harder to get Robert to accept it now.
I think that (for such a major change) the transition went fairly smoothly. We still have the option to revert throw_exception if the "broad discussion" that should have happened then but is happening now reaches this conclusion.
I'm not sure it's the right conclusion to reach, but I do want to discuss it.
Either way, we'll still be ahead of where we were, both because we now have BOOST_NO_RTTI and some awareness of its significance, and because the new throw_exception caught a few bugs.
The impression I get is that for you, those benefits outweigh the costs by such a wide margin that the costs aren't even worth mentioning. Is that right? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Wed, Aug 27, 2008 at 12:27 PM, David Abrahams
So IIUC, your intention was never to require RTTI in throw_exception, and Emil didn't know that, so he violated your original intent unwittingly.
No, the problem is that essentially we have a bug that was undiscovered until users pointed it out. My intention was to disable the integration of Boost Exception in boost::throw_exception if RTTI is not available. My wrong understanding was that using BOOST_NO_TYPEID accomplishes that, but it doesn't. Now we have BOOST_NO_RTTI. I will plug that in some time this week; I thought that this change isn't urgent because we are not making point releases. Until then, as indicated by the Boost Exception documentation, users can disable the integration by defining BOOST_EXCEPTION_DISABLE (I know, poor name choice, since it doesn't disable exceptions.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

on Wed Aug 27 2008, "Emil Dotchevski" <emil-AT-revergestudios.com> wrote:
On Wed, Aug 27, 2008 at 12:27 PM, David Abrahams
So IIUC, your intention was never to require RTTI in throw_exception, and Emil didn't know that, so he violated your original intent unwittingly.
No, the problem is that essentially we have a bug that was undiscovered until users pointed it out.
My intention was to disable the integration of Boost Exception in boost::throw_exception if RTTI is not available. My wrong understanding was that using BOOST_NO_TYPEID accomplishes that, but it doesn't.
Ah, thanks for clarifying that.
Now we have BOOST_NO_RTTI. I will plug that in some time this week; I thought that this change isn't urgent because we are not making point releases.
Sounds right. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Wed, Aug 27, 2008 at 12:27 PM, David Abrahams <dave@boostpro.com> wrote:
What about the "weight" of the header and its dependencies? Your usual stance is to avoid such things.
It is my usual stance as well. :) The part of the exception library that is pulled in by boost::throw_exception is specifically designed for that purpose. Besides a few lightweight definitions, this only pulls in atomic_count and intrusive_ptr. If someone can think of a way to avoid these dependencies, I'm all ears. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

on Wed Aug 27 2008, "Emil Dotchevski" <emil-AT-revergestudios.com> wrote:
On Wed, Aug 27, 2008 at 12:27 PM, David Abrahams <dave@boostpro.com> wrote:
What about the "weight" of the header and its dependencies? Your usual stance is to avoid such things.
It is my usual stance as well. :)
The part of the exception library that is pulled in by boost::throw_exception is specifically designed for that purpose. Besides a few lightweight definitions, this only pulls in atomic_count and intrusive_ptr.
Well, it's about 4K lines of code.
If someone can think of a way to avoid these dependencies, I'm all ears.
I don't know of a way. BTW, it's just a guess, but I think a more traditional choice of where to add newlines in your code *might* have muted Robert's "I have no idea what this code does" reaction. Of course, the best way to avoid that is to explain it to the maintainers of all affected libraries beforehand. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

2008/8/28 David Abrahams <dave@boostpro.com>:
Of course, the best way to avoid that is to explain it to the maintainers of all affected libraries beforehand.
Well, that's the problem. It's remarkably hard to get their attention. I think it's unfair to expect a new developer to seek out the appropriate developers and pester them individually - and that is what it would take. IMO the biggest problem that boost has is this kind of communication, not point releases, version control or breaking interfaces. I've been on both sides of this problem and it's very frustrating. Important issues are constantly getting lost in the noise of the lists and are only picked up when it's too late.

----- Original Message ----- From: "David Abrahams" <dave@boostpro.com> To: <boost@lists.boost.org> Sent: Wednesday, August 27, 2008 8:13 PM Subject: [boost] [exception][policy] (was: Should we provide hot fixes?)
on Wed Aug 27 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
I'm referring specificly to the episode regarding boost exception where by the purpose of boost::throw exception was changed from a limited, lightweight piece of code crafted to address the simple problem that some compilers don't implement "throw" to a heavy weight (includes a bunch of new headers) module whose purpose is totally inpenetrable and adds RTTI requirement to any library which used boost::throw exception.
This does look like a problem to me.
Hi, I also think that this was a bad decision. When we use boost::throw we don't want to pay for the case the exception must be transfered to another thread. This must be paid only on the current_exception function, when we want to transfer to another thread. This should be done using a specific boost::exception_ptr::throw function. The main problem comes from the fact exception_ptr current_exception() do not works for any exception. So Emil has found that boost::throw could be used to throw a boost::exception wrapping the intendeed exception. IMHO, the exception_ptr emulation (without language support) to transport exceptions between threads is not of real use if current_exception() do not works for any exception. If we were able to ensure that current_exception manage all exceptions we dont will need that boost::throw wrappes a exception on a exception_ptr. As Anthony has said some compilers (as MSVC) allows to recover the current exception, so for this compilers should not be a problem when Emil introduce this in the Exception library. For the other compilers we need a mechanism that allows the user to configure the exceptions that needs to be wrapped with a boost::exception_ptr as the Exception library do already for the STL exceptions. A few months ago I proposed an intrusive way (using the preprocesor) allowing the user to define which exceptions will be wrapped by boost::exception_ptr (see http://www.nabble.com/Re%3A--Boost-users---Boost.thread--Exception-handling-... for details). I want to propose now another approach using a chain of responsabilities. The trick consists in replacing the catch(...) handler which currently returns a exception_detail::current_exception_unknown_exception() by a user specific one. inline exception_ptr current_exception() { try { throw; } // ... as before catch( ... ) { return (*boost::user_current_exception_handler)(); } } The default user_current_exception_handler will return a exception_detail::current_exception_unknown_exception() as it is done now. The user current exception handlers have the responsability to return a exception_ptr wrapping the exception managed, and call to the next exception handler on the catch(...). The exception library needs to provide a way to set this user_current_exception_handler returning the old one. inline exception_ptr (*)() set_user_current_exception_handler(exception_ptr (*new_handler)() ) { exception_ptr (*old_handler)() = boost::user_current_exception_handler; boost::user_current_exception_handler=new_handler; return old_handler; } Evidently this function is not thread_safe. Then a user can define its own current_exception_handler as follows: exception_ptr X_current_exception_handler() { try { throw; } // catch my own exceptions catch(X_exception_1 & e ) { return exception_detail::current_exception_std_exception(e); } // ... catch(X_exception_k & e ) { return exception_detail::current_exception_std_exception(e); } catch( ... ) { return (*X_next_current_exception_handler)(); } } Let me continue with the initialization of the X_next_current_exception_handler. This can be done in a simple way on the main thread X_next_current_exception_handler=set_user_current_exception_handler(my_current_exception_handler); or we can think in a more elaborated way, using static initialization. As static initialization is done sequentially, there is no problem with the non thread safety of the set_user_current_exception_handler. But I don't know how to ensure that the boost::user_current_exception_handler is initialized before the user ones other than including all the user next current exception handler in the same compilation unit as the boost::user_current_exception_handler. The Exception library could define a type that do the set of the next handler at construction time. class exception_handler_participant { exception_ptr (*next_)() ; public: exception_handler_setter(exception_ptr (*new_handler)()) { next_ = set_user_current_exception_handler(new_handler); } exception_ptr next() { return (*next_)(); } }; Each library/application can declare its own current exception handler participant in a header file and define it in a specific _def.cpp file wich will be included by the application. // X_current_exception_handler_participant_def.cpp // include whathever is needed static const boost::exception::current_exception_handler_participant X_current_exception_handler_participant(X_current_exception_handler); and define its handler as exception_ptr X_current_exception_handler() { try { throw; } // catch my own exceptions catch(X_exception_1 & e ) { return exception_detail::current_exception_std_exception(e); } // ... catch(X_exception_k & e ) { return exception_detail::current_exception_std_exception(e); } catch( ... ) { return X_current_exception_handler_participant.next(); } } The final user will include all the participants definitions in a unique file in order to ensure the static initialization order. // final_user_current_exception_handler_participants_def.cpp #include <boost/exception/user_current_exception_handler_def.cpp> #include <Alib_current_exception_handler_participant_def.cpp> #include <Blib_current_exception_handler_participant_def.cpp> #include <X_current_exception_handler_participant_def.cpp> The runtime approach is more time consuming than the preprocesor one, but do not have the preprocesor limitation that do not works when the function using the current_exception is declared in a file that is not compiled by the final user, i.e. it is contained in a static or dynamic library. There is yet a limitation: the behavior of calling current_exception on the constructor of a statically variable is undefined because we can not ensure that the current_exception_handler_participants static variables have been initialized. But this seams to me a minor limitation. What do you think? Vicente

On Thu, Aug 28, 2008 at 9:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
The main problem comes from the fact exception_ptr current_exception() do not works for any exception. So Emil has found that boost::throw could be used to throw a boost::exception wrapping the intendeed exception. IMHO, the exception_ptr emulation (without language support) to transport exceptions between threads is not of real use if current_exception() do not works for any exception.
As per http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html current_exception works for any exception. This is what we should aim for. Antony has already provided a MSVC-specific implementation that works for any exception. As soon as I find the time to integrate this into Boost Exception, boost::enable_current_exception will be a noop on MSVC. In principle, every compiler has the machinery necessary to implement current_exception completely non-intrusively. I am not a compiler expert, but it seems likely that compiler-specific solution should be possible for GCC as well. In my opinion boost::exception_ptr provides very useful functionality. It is enabled by boost::enable_current_exception, which boost::throw_exception allows us to inject non-intrusively. If the cost of boost::enable_current_exception is a problem, this can be viewed as a motivating force to provide compiler-specific non-intrusive support for boost::exception_ptr (however I request that we don't discuss the cost of boost::enable_current exception until I get a chance to fully test the refactoring pass I've done on the exception library.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
On Thu, Aug 28, 2008 at 9:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
The main problem comes from the fact exception_ptr current_exception() do not works for any exception. So Emil has found that boost::throw could be used to throw a boost::exception wrapping the intendeed exception. IMHO, the exception_ptr emulation (without language support) to transport exceptions between threads is not of real use if current_exception() do not works for any exception.
As per http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html current_exception works for any exception. This is what we should aim for.
Antony has already provided a MSVC-specific implementation that works for any exception. As soon as I find the time to integrate this into Boost Exception, boost::enable_current_exception will be a noop on MSVC.
In principle, every compiler has the machinery necessary to implement current_exception completely non-intrusively. I am not a compiler expert, but it seems likely that compiler-specific solution should be possible for GCC as well.
No. I've tried, and it doesn't work. On the positive side, GCC 4.4 will have native support for exception_ptr for some platforms (not x86, but x86_64), and GCC 4.5 will hopefully support it everywhere. Sebastian

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Friday, August 29, 2008 8:57 PM Subject: Re: [boost] [exception][policy]
On Thu, Aug 28, 2008 at 9:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
The main problem comes from the fact exception_ptr current_exception() do not works for any exception. So Emil has found that boost::throw could be used to throw a boost::exception wrapping the intendeed exception. IMHO, the exception_ptr emulation (without language support) to transport exceptions between threads is not of real use if current_exception() do not works for any exception.
As per http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html current_exception works for any exception. This is what we should aim for.
not works for any exception" I was talking about the current implementation of exception_ptr current_exception() by the Boost::Exception library. I'm aware that n2179 require that current_exception MUST work for any exception. This is exactly what my proposal intend to provide. BTW, if current_exception works for any exception, we don't need anymore
Hi Emil, Evidently when I said"exception_ptr current_exception() do that boost::throw_exception use boost::enable_current_exception, isn't it? And in this case we can come back to the old behavior of boost::throw_exception as requested by Robert.
Antony has already provided a MSVC-specific implementation that works for any exception. As soon as I find the time to integrate this into Boost Exception, boost::enable_current_exception will be a noop on MSVC.
In principle, every compiler has the machinery necessary to implement current_exception completely non-intrusively. I am not a compiler expert, but it seems likely that compiler-specific solution should be possible for GCC as well.
I don't know every compiler so I prefere Boost::Exception provides a solution that works when the compiler do not has the machinery necessary to implement current_exception completely non-intrusively. Evidently, when the compiler provide the mechanism, current_exception will not use the the user_current_exception_handler, and the setting of this handlers will be a noop.
In my opinion boost::exception_ptr provides very useful functionality. It is enabled by boost::enable_current_exception, which boost::throw_exception allows us to inject non-intrusively. If the cost of boost::enable_current_exception is a problem, this can be viewed as a motivating force to provide compiler-specific non-intrusive support for boost::exception_ptr (however I request that we don't discuss the cost of boost::enable_current exception until I get a chance to fully test the refactoring pass I've done on the exception library.)
I'm not questioning the usefulness of boost::exception_ptr. I'm only stating that in the current release, current_exception do not works for any exception (do not transfer every exception between threads) as required by n2179. What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception. My proposal allows the final user to complete *intrusively* the list of exceptions for which current_exception will work, having as default behavior the one of the current release. What objections do you have to my proposal? Regards, Vicente

On Sat, Aug 30, 2008 at 5:29 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
BTW, if current_exception works for any exception, we don't need anymore that boost::throw_exception use boost::enable_current_exception, isn't it?
More accurately, on platforms where current_exception can work for any exception without support from enable_current_exception, enable_current_exception can be noop.
I'm not questioning the usefulness of boost::exception_ptr. I'm only stating that in the current release, current_exception do not works for any exception (do not transfer every exception between threads) as required by n2179. What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception.
My proposal allows the final user to complete *intrusively* the list of exceptions for which current_exception will work, having as default behavior the one of the current release. What objections do you have to my proposal?
What use case do you have in mind? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Saturday, August 30, 2008 7:33 PM Subject: Re: [boost] [exception][policy]
On Sat, Aug 30, 2008 at 5:29 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
BTW, if current_exception works for any exception, we don't need anymore that boost::throw_exception use boost::enable_current_exception, isn't it?
More accurately, on platforms where current_exception can work for any exception without support from enable_current_exception, enable_current_exception can be noop.
More accurately, on platforms where current_exception can work for any exception, the file containing boost::throw_exception MUST not depend on the file containing enable_current_exception.
I'm not questioning the usefulness of boost::exception_ptr. I'm only stating that in the current release, current_exception do not works for any exception (do not transfer every exception between threads) as required by n2179. What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception.
My proposal allows the final user to complete *intrusively* the list of exceptions for which current_exception will work, having as default behavior the one of the current release. What objections do you have to my proposal?
What use case do you have in mind?
Sorry, but I dont understand your question. What use case do I have in mind for what? Maybe you can question is related to:"What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception." Vicente

On Sat, Aug 30, 2008 at 7:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What use case do you have in mind?
Sorry, but I dont understand your question. What use case do I have in mind for what? Maybe you can question is related to:"What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception."
I am trying to be as objective as possible in answering your previous questions. For that, I need to understand what is the use case you have in mind. I understand that it involves a 3rd party library throwing an exception, but more details please: - who catches the exception initially? - who copies it into an exception_ptr? - who rethrows it? - who catches it after the rethrow? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Sunday, August 31, 2008 5:30 AM Subject: Re: [boost] [exception][policy]
On Sat, Aug 30, 2008 at 7:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What use case do you have in mind?
Sorry, but I dont understand your question. What use case do I have in mind for what? Maybe you can question is related to:"What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception."
I am trying to be as objective as possible in answering your previous questions. For that, I need to understand what is the use case you have in mind. I understand that it involves a 3rd party library throwing an exception, but more details please:
Emil, My own application request a thread pool library to execute a function F asynchronously
- who catches the exception initially?
A thread pool (packaged_task) library, which calls the function F calling a 3pp function 3ppF throwing an exception (3pp_exception1 or 3pp_exception2)
- who copies it into an exception_ptr?
the same thread pool (packaged_task) library calls the current_exception and stores the exception_ptr in the future associates to the packaged task.
- who rethrows it?
The thread pool (packaged_task) Library which rethrow the stored exception when the user wait on the future value.
- who catches it after the rethrow?
My own application, which requested a thread pool library to execute the function F Emil, while answering your question I see that I was wrong when I said that "final user can not do anything for the exceptions thrown by 3pp libraries": The final user can define a function Ftry_catch wich wraps the call to the function F by a try-catch, use the boost:throw_exception to throw each one of the exceptions 3ppF can throw, and request the thread pool library to execute the function Ftry_catch instead. Was this what you mean? Do you think that it is raisonable that every user of the thread_pool library must wraps each packaged_task function in order to ensure that the exception are transported between threads? Should the user be aware of which compilers don't need this wrapping because current_exception works for every exception? What do you think about a functor class that do all this stuff, something like (not correct C++ code)? template <result_type (*FUNCTION)(arg1_type, ..., argk_type), typename EXCP1, ..., typename EXCPN> class try_catch { public: result_type operator()(arg1_type p1, ..., argk_type pk) { try { return FUNCTION(p1, ..., pk); } catch (EXCP1& e) { boost::throw_exception(e); ... } catch (EXCPN& e) { boost::throw_exception(e); } catch (...) { throw; } } }; try_catch<F, 3pp_exception1, 3pp_exception2> Ftry_catch; packaged_task(Ftry_catch); Thanks, Vicente

On Sun, Aug 31, 2008 at 8:54 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
On Sat, Aug 30, 2008 at 7:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What use case do you have in mind?
Sorry, but I dont understand your question. What use case do I have in mind for what? Maybe you can question is related to:"What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception."
I am trying to be as objective as possible in answering your previous questions. For that, I need to understand what is the use case you have in mind. I understand that it involves a 3rd party library throwing an exception, but more details please:
My own application request a thread pool library to execute a function F asynchronously
- who catches the exception initially?
A thread pool (packaged_task) library, which calls the function F calling a 3pp function 3ppF throwing an exception (3pp_exception1 or 3pp_exception2)
- who copies it into an exception_ptr?
the same thread pool (packaged_task) library calls the current_exception and stores the exception_ptr in the future associates to the packaged task.
- who rethrows it?
The thread pool (packaged_task) Library which rethrow the stored exception when the user wait on the future value.
- who catches it after the rethrow?
My own application, which requested a thread pool library to execute the function F
Emil, while answering your question I see that I was wrong when I said that "final user can not do anything for the exceptions thrown by 3pp libraries": The final user can define a function Ftry_catch wich wraps the call to the function F by a try-catch, use the boost:throw_exception to throw each one of the exceptions 3ppF can throw, and request the thread pool library to execute the function Ftry_catch instead. Was this what you mean?
I didn't mean anything in particular, I just wanted to understand the problem you are trying to solve. :) Your function wrapper solution is a possibility. Another possibility is, if the thread pool library is not third party, it can implement your original idea of exception registry. Such use cases are supported by boost::copy_exception: catch( something & x ) { boost::exception_ptr p=boost::copy_exception(x); ... } Note however that after an exception is thrown without using boost::enable_current_exception, it is already too late for a general solution because it might be unsafe or impossible to copy the type you catch. For example, this will not work: catch( boost::exception & x ) { boost::exception_ptr p=boost::copy_exception(x); } You'd get a compile error, because boost::exception is abstract. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

I just realized that the released boost::copy_exception documentation is incomplete. Here is the correct documentation: http://svn.boost.org/svn/boost/trunk/libs/exception/doc/copy_exception.html Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Sunday, August 31, 2008 8:59 PM Subject: Re: [boost] [exception][policy]
On Sun, Aug 31, 2008 at 8:54 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
On Sat, Aug 30, 2008 at 7:21 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What use case do you have in mind?
Sorry, but I dont understand your question. What use case do I have in mind for what? Maybe you can question is related to:"What is worst is that the final user can not do anything for the exceptions thrown by 3pp libraries that do not use boost::enable_current_exception or boost::throw_exception."
I am trying to be as objective as possible in answering your previous questions. For that, I need to understand what is the use case you have in mind. I understand that it involves a 3rd party library throwing an exception, but more details please:
My own application request a thread pool library to execute a function F asynchronously
- who catches the exception initially?
A thread pool (packaged_task) library, which calls the function F calling a 3pp function 3ppF throwing an exception (3pp_exception1 or 3pp_exception2)
- who copies it into an exception_ptr?
the same thread pool (packaged_task) library calls the current_exception and stores the exception_ptr in the future associates to the packaged task.
- who rethrows it?
The thread pool (packaged_task) Library which rethrow the stored exception when the user wait on the future value.
- who catches it after the rethrow?
My own application, which requested a thread pool library to execute the function F
Emil, while answering your question I see that I was wrong when I said that "final user can not do anything for the exceptions thrown by 3pp libraries": The final user can define a function Ftry_catch wich wraps the call to the function F by a try-catch, use the boost:throw_exception to throw each one of the exceptions 3ppF can throw, and request the thread pool library to execute the function Ftry_catch instead. Was this what you mean?
I didn't mean anything in particular, I just wanted to understand the problem you are trying to solve. :)
Your function wrapper solution is a possibility. Another possibility is, if the thread pool library is not third party, it can implement your original idea of exception registry.
Can my original idea of exception registry be implemented by the Boost.Exception library? Vicente

On Sun, Aug 31, 2008 at 11:33 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
Can my original idea of exception registry be implemented by the Boost.Exception library?
What are the benefits of the "exception registry" over the "function wrapper" approach that you mentioned? Do you have a use case where the "function wrapper" wouldn't work, but the "exception registry" would? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Monday, September 01, 2008 9:51 PM Subject: Re: [boost] [exception][policy]
On Sun, Aug 31, 2008 at 11:33 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
Can my original idea of exception registry be implemented by the Boost.Exception library?
What are the benefits of the "exception registry" over the "function wrapper" approach that you mentioned?
Maybe my initial "exception registry" proposal has some drawbacks and need to be pollished. The benefits I see are: * The exception_registry will be done once for all and will profit to every user of the exception_ptr library, while the wrapping approach forces every user to wrap its functions. * The wrapping approach has one try-catch block more than the exception_registry approach, so less performant. * The exception_registry approach centralize the knowledge of which compilers provides the mechanisms to ensure that current_exception works for any exception on the Boost.Exception library. The wrapping approach on the best case split this knowledge into two libraries, and if the try_catch functor class do not exists, into each user of the current_exception function direct or indirect. Do you see any benefits of the "function wrapper" over the "exception registry" approach? Please, let me know if you have a use case where the exception_registry proposal do not work? I'm really interested in seen if together we can get a better solution.
Do you have a use case where the "function wrapper" wouldn't work, but the "exception registry" would?
No, not now. I was asking this only because I think that it is a better solution to include it in the Exception library and also because you were proposing this for the thread_pool library. Quotting you from your preceding post : "Your function wrapper solution is a possibility. Another possibility is, if the thread pool library is not third party, it can implement your original idea of exception registry." So, if you think that this could be a possibility for the thread_pool library, it should be even better for the exception library, because in this way, other libraries will profit of this commonality, isn't it? Best, Vicente

On Mon, Sep 1, 2008 at 2:34 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
Do you have a use case where the "function wrapper" wouldn't work, but the "exception registry" would?
No, not now. I was asking this only because I think that it is a better solution to include it in the Exception library and also because you were proposing this for the thread_pool library.
In my mind both approaches are about the same, except that the wrapper approach is decoupled from the exception library. It's not that I like it better, but it can be implemented on top of the current exception library interface. I certainly don't want to add anything to Boost Exception without knowing that someone has a use case for that.
Quotting you from your preceding post : "Your function wrapper solution is a possibility. Another possibility is, if the thread pool library is not third party, it can implement your original idea of exception registry." So, if you think that this could be a possibility for the thread_pool library, it should be even better for the exception library, because in this way, other libraries will profit of this commonality, isn't it?
What is "the" tread_pool library we're talking about? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

----- Original Message ----- From: "Emil Dotchevski" <emil@revergestudios.com> To: <boost@lists.boost.org> Sent: Tuesday, September 02, 2008 5:50 AM Subject: Re: [boost] [exception][policy]
On Mon, Sep 1, 2008 at 2:34 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
Do you have a use case where the "function wrapper" wouldn't work, but the "exception registry" would?
No, not now. I was asking this only because I think that it is a better solution to include it in the Exception library and also because you were proposing this for the thread_pool library.
In my mind both approaches are about the same, except that the wrapper approach is decoupled from the exception library. It's not that I like it better, but it can be implemented on top of the current exception library interface.
I would like to know which approach is prefered by the boost user/developpers, have some of you a preference?
I certainly don't want to add anything to Boost Exception without knowing that someone has a use case for that.
You are right, it is a good principle. I have a use case with two possibilities. You have find that it was a possibility for a thread_pool library for which a more coupled approach was not a problem. This thread was started because the throw_exception function has coupled to the Boost.Exception library. A user could wrap the throw_exception function and do whatever you do in. What is the difference? What is wrong then in couplig a register_exception mechanis to ensure the *correct* semantics of the current_exception function?
Quotting you from your preceding post : "Your function wrapper solution is a possibility. Another possibility is, if the thread pool library is not third party, it can implement your original idea of exception registry." So, if you think that this could be a possibility for the thread_pool library, it should be even better for the exception library, because in this way, other libraries will profit of this commonality, isn't it?
What is "the" thread_pool library we're talking about?
The thread_pool library of my use case of course. It can also be any library using the exception_ptr current_exception as the already proposed for review Future library (packaged_task) library by Anthony, the porting of the FTTask ("A Java Fork/Join Framework" http://gee.cs.oswego.edu/dl/papers/fj.pdf) to C++/boost I would like to do, ... I'd be interested in knowing what other boost::current_exception users think? Anthony? Vicente

At 2:06 PM -0800 8/26/08, Robert Ramey wrote:
Marshall Clow wrote:
At 10:38 PM +0200 8/26/08, Christian Larsen wrote:
Basically, you can never remove an interface, because someone, somewhere might be using it.
That's basically correct - that's why in general you should only extend an interface or make a new interface. To do otherwise breaks faith with the users of your library.
No problem if you want to create a new interface - just give it a new name.
There's something wrong in the quoting here. I was the one that wrote: Basically, you can never remove an interface, because someone, somewhere might be using it. but Robert removed the line before that, where I said: But that way lies madness. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

I wrote:
I was the one that wrote: Basically, you can never remove an interface, because someone, somewhere might be using it.
but Robert removed the line before that, where I said: But that way lies madness.
Another correction (this time on my part). I don't know that Robert removed that line; just that someone did. Sorry to cast aspersions. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

Marshall Clow wrote:
I wrote:
I was the one that wrote: Basically, you can never remove an interface, because someone, somewhere might be using it.
but Robert removed the line before that, where I said: But that way lies madness.
Another correction (this time on my part). I don't know that Robert removed that line; just that someone did. Sorry to cast aspersions.
I removed the line by accident, sorry. Actually, I totally mis-interpreted what you said. I took it to mean that the statement suggested that the madness lies in the idea that you can never remove an interface. If I understand now, you're in agreement that removing or changing an existing interface creates a lot of problems (madness?) and that using a new name is the preferred method? Robert Ramey

on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Marshall Clow wrote:
I wrote:
I was the one that wrote: Basically, you can never remove an interface, because someone, somewhere might be using it.
but Robert removed the line before that, where I said: But that way lies madness.
Another correction (this time on my part). I don't know that Robert removed that line; just that someone did. Sorry to cast aspersions.
I removed the line by accident, sorry.
Actually, I totally mis-interpreted what you said. I took it to mean that the statement suggested that the madness lies in the idea that you can never remove an interface. If I understand now, you're in agreement that removing or changing an existing interface creates a lot of problems (madness?) and that using a new name is the preferred method?
I think you had it right the first time. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

At 5:37 AM -0800 8/27/08, David Abrahams wrote:
on Tue Aug 26 2008, "Robert Ramey" <ramey-AT-rrsd.com> wrote:
Marshall Clow wrote:
I wrote:
I was the one that wrote: Basically, you can never remove an interface, because someone, somewhere might be using it.
but Robert removed the line before that, where I said: But that way lies madness.
Another correction (this time on my part). I don't know that Robert removed that line; just that someone did. Sorry to cast aspersions.
I removed the line by accident, sorry.
Actually, I totally mis-interpreted what you said. I took it to mean that the statement suggested that the madness lies in the idea that you can never remove an interface. If I understand now, you're in agreement that removing or changing an existing interface creates a lot of problems (madness?) and that using a new name is the preferred method?
I think you had it right the first time.
Dave is correct. I meant that never removing interfaces is madness. Anyone remember the interface for iterators before the STL? iter = <whatever> while ( iter.more ()) { // do stuff iter.next (); } Should iterators still support this - or is it a good thing that Stepanov (and others) decided that they had a better way? [ This is not just syntax, btw ] -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

Marshall Clow wrote:
Dave is correct. I meant that never removing interfaces is madness.
Anyone remember the interface for iterators before the STL? iter = <whatever> while ( iter.more ()) { // do stuff iter.next (); }
before STL? Wasn't std a new namespace? Didn't it require inclusion of a new header? That would qualify as name change. I have no idea about the above code but I don't think introduction of STL would prevent it compiling and running.
Should iterators still support this - or is it a good thing that Stepanov (and others) decided that they had a better way? [ This is not just syntax, btw ]
If I have a header x.hpp and I compile my code in the year 2000 I should be able to recompile it in the year 2008 without having to debug it again. Robert Ramey

On Wed, Aug 27, 2008 at 1:33 PM, Robert Ramey <ramey@rrsd.com> wrote:
Marshall Clow wrote:
Dave is correct. I meant that never removing interfaces is madness.
[snip]
Should iterators still support this - or is it a good thing that Stepanov (and others) decided that they had a better way? [ This is not just syntax, btw ]
If I have a header x.hpp and I compile my code in the year 2000 I should be able to recompile it in the year 2008 without having to debug it again.
You are arguing about backward-compatibility and STL didn't offered backward-compatibility with the standardization process. Of course you can compile that same code with that same dependency the same before as you can now. But the same is true with boost 1.33. You just can't upgrade it.
Robert Ramey
-- Felipe Magno de Almeida

Marshall Clow wrote:
Changing interfaces, to me, implies that the developer: * Discovered a better way to solve the problem that he faced. * Decided that the benefits of the change outweighed the costs.
The "don't change interfaces, ever, no matter what" is why we still have "strcpy" and "mktmp", to name just two examples. Bad interfaces are bugs; they should be fixed.
Software does not spring full-blown from someone's forehead; it is a process of discovery and refinement. Interfaces follow that same path.
True enough, but it's still good manners to try and preserve source-compatibility even if binary-compatibility can't be preserved. Cheers, John.

Quoting John Maddock <john@johnmaddock.co.uk>:
Software does not spring full-blown from someone's forehead; it is a process of discovery and refinement. Interfaces follow that same path.
True enough, but it's still good manners to try and preserve source-compatibility even if binary-compatibility can't be preserved.
And those two conflicting aims are why big projects always end up with a formalized deprecation procedure. Progress can be made, but users aren't stomped on too hard. I like how the Spirit developers are using BOOST_VERSION to control when warnings re the Spirit.V1 namespace move will appear. Perhaps that method could form the baseline to any more formal Boost deprecation procedure that may result from this discussion. Pete

on Tue Aug 26 2008, Christian Larsen <contact-AT-dword.dk> wrote:
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
People who want point releases aren't just asking for what we _think_ will be "no interface-breaking changes," because the best we can do is guess. Who knows what the effects will actually be on their platform in their environment? They're asking for the release, exactly as it was, plus bugfixes. That's it. No new features, no new libraries, period. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Tue Aug 26 2008, Christian Larsen <contact-AT-dword.dk> wrote:
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
People who want point releases aren't just asking for what we _think_ will be "no interface-breaking changes," because the best we can do is guess. Who knows what the effects will actually be on their platform in their environment? They're asking for the release, exactly as it was, plus bugfixes. That's it. No new features, no new libraries, period.
As a long time user of boost, I agree, almost 100%. :) 99.9% of the time, a point fix should make no interface change. Unfortunately, there is that .1% where the only way to fix a bug is to change the interface. So we ought to discourage header file changes in point releases unless it is demonstrated that either it is backwards compatible or else there's no other way to fix the bug. -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org

on Tue Aug 26 2008, Jonathan Biggar <jon-AT-biggar.org> wrote:
David Abrahams wrote:
on Tue Aug 26 2008, Christian Larsen <contact-AT-dword.dk> wrote:
Yes, that's right. But still I don't see how that would make it possible to keep a stable interface, and make point releases of that. Unless all developers agree to only merge non-interface breaking changes into "ReleaseReady".
People who want point releases aren't just asking for what we _think_ will be "no interface-breaking changes," because the best we can do is guess. Who knows what the effects will actually be on their platform in their environment? They're asking for the release, exactly as it was, plus bugfixes. That's it. No new features, no new libraries, period.
As a long time user of boost, I agree, almost 100%. :)
99.9% of the time, a point fix should make no interface change. Unfortunately, there is that .1% where the only way to fix a bug is to change the interface.
Granted. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
This has firmed up: there will be no point releases until quarterly releases are working very smoothly and we have enough resources to integrate point releases into our quarterly workflow.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
I'm going to try providing some Filesystem patches to see if users find them helpful. I've tried to incorporate several comments from this thread into the instructions. See http://svn.boost.org/trac/boost/wiki/ReleasePractices/HotFixes If any other developers would like to post 1.36.0 patches, please feel free to add them to the above page. --Beman

Beman Dawes wrote:
I'm going to try providing some Filesystem patches to see if users find them helpful. I've tried to incorporate several comments from this thread into the instructions.
See http://svn.boost.org/trac/boost/wiki/ReleasePractices/HotFixes
If any other developers would like to post 1.36.0 patches, please feel free to add them to the above page.
IMO, this is not a bad thing to try, but if we want people to find it and use it, we would need to put a link to it somewhere on boost.org. Maybe under "Support"? FWIW, I've added a link to an Xpressive patch. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Beman Dawes wrote:
I'm going to try providing some Filesystem patches to see if users find them helpful. I've tried to incorporate several comments from this thread into the instructions.
See http://svn.boost.org/trac/boost/wiki/ReleasePractices/HotFixes
If any other developers would like to post 1.36.0 patches, please feel free to add them to the above page.
IMO, this is not a bad thing to try, but if we want people to find it and use it, we would need to put a link to it somewhere on boost.org. Maybe under "Support"?
Yes, for sure. But first I wanted to let the developer's list know in case anyone spotted serious flaws in the procedure.
FWIW, I've added a link to an Xpressive patch.
Interesting. You give the path as "boost-root" in the table, because the patch applies to both boost/xpressive/detail/utility and boost/xpressive/detail/utility. But then patch gets an error "can't find file to patch at input line 5" To work correctly, the commands needs to be: cd boost-root patch -p 2 <download-path/changeset_r48141.diff Hum... Won't that set of commands work for all patch files? That would simplify the instructions and allow dropping the Directory column from the table. I'd appreciate it if several people would try that on their systems and verify it works. Thanks, --Beman

Beman Dawes wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
This has firmed up: there will be no point releases until quarterly releases are working very smoothly and we have enough resources to integrate point releases into our quarterly workflow.
To get bug fixes into user's hands more quickly, should we provide hot fixes when appropriate?
I'm going to try providing some Filesystem patches to see if users find them helpful. I've tried to incorporate several comments from this thread into the instructions.
See http://svn.boost.org/trac/boost/wiki/ReleasePractices/HotFixes
How is this different from providing an untested 'HotFixes' or 'point-release' branch?

Beman Dawes wrote:
Beman Dawes wrote:
Although it does look like we will be able to hold to a quarterly release schedule, it is really doubtful we have enough resources to issue point releases.
This has firmed up: there will be no point releases until quarterly releases are working very smoothly and we have enough resources to integrate point releases into our quarterly workflow.
I'm not sure I'm understand what "resources" you have in mind. What you propose is essentially: - Post 1.36.0 release, duly tested and packaged - Post a set of hotfixes Another alternative is - Post 1.36.0 release, duly tested and packaged - Post 1.36.1 Now, if the 1.36+hotfixes are tested as extensively as the real release, then you already spend the resources, the only extra effort is packaging. If, for whatever reason, it is decided that hotfixes are obvious enough as to don't require any testing, then 1.36.1 package, incorporating the same hotfixes, can be released without any testing too. In other words, the only extra effort for point release is packaging. Are you saying there are not enough manpower for packaging, or I've missed something? - Volodya

Vladimir Prus wrote:
What you propose is essentially:
- Post 1.36.0 release, duly tested and packaged - Post a set of hotfixes
Another alternative is
- Post 1.36.0 release, duly tested and packaged - Post 1.36.1
Now, if the 1.36+hotfixes are tested as extensively as the real release, then you already spend the resources, the only extra effort is packaging. If, for whatever reason, it is decided that hotfixes are obvious enough as to don't require any testing, then 1.36.1 package, incorporating the same hotfixes, can be released without any testing too.
Actually, wouldn't testing the N hotfixes require testing all 2^N - 1 possibilities? That is, since each hotfix could be tested independently, we would really need to test every combination of applying/not applying the hotfixes (except the case of not applying any of them, thus the -1). Releasing a point release would only require testing possibility (that corresponds to applying all of the hotfixes). So it seems like testing hotfixes requires considerably more work than testing a point release. David

David Walthall wrote:
Vladimir Prus wrote:
Actually, wouldn't testing the N hotfixes require testing all 2^N - 1 possibilities? That is, since each hotfix could be tested independently, we would really need to test every combination of applying/not applying the hotfixes (except the case of not applying any of them, thus the -1). Releasing a point release would only require testing possibility (that corresponds to applying all of the hotfixes). So it seems like testing hotfixes requires considerably more work than testing a point release.
LOL - very good point ! I wish I had thought of that! I must say that I don't like the hotfixe point release idea. I think if we required that each each library merge into the release ready branch requires in no new failues, that should be enough. Anyone who want's just part of it can do the work himself. I mean its only a question of re-running the test-suite on one's own machine - which a prudent should be doing anyway. Robert Ramey
participants (23)
-
Anteru
-
Beman Dawes
-
Christian Larsen
-
Daniel James
-
Daniel Wallin
-
David Abrahams
-
David Walthall
-
Dean Michael Berris
-
dherring@ll.mit.edu
-
Emil Dotchevski
-
Eric Niebler
-
Felipe Magno de Almeida
-
Gubenko, Boris
-
Ilya Sokolov
-
John Maddock
-
Jonathan Biggar
-
Marshall Clow
-
Peter Bartlett
-
Peter Dimov
-
Robert Ramey
-
Sebastian Redl
-
vicente.botet
-
Vladimir Prus