[outcome] non-interface-related concerns
The discussion mostly revolves around the design of the interface of `outcome::expected` and even `std::expected`. My questions here are about the way this library will be distributed to users. And I am uncomfortable with the situation. I am not necessarily saying it is wrong, but I do not understand what is going on here. 1. The current GitHub repository consists of sub-repos. Do you (Niall) plan to have it like this when the library is accepted? Is it relevant? 2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it controls whether I use this "preprocessed" file versus if I use... what? Normal header files? What is gained by this preprocessed file? Not having to include more than one header, or something else? Can I get different results when compiling with and without this macro? 3. I am recommended to use this macro BOOST_OUTCOME_V1_NAMESPACE. I am told it has something to do with ABI stability? Can you elaborate on how this guarantees ABI stability. Or is its purpose different? I have a certain problem with understanding this philosophy. A couple of days back, I reported the compilation failure in MinGW. I can see that the issue (https://github.com/ned14/boost.outcome/issues/36) is reorted as fixed in branch 'develop'. I would like to confirm that the bug is fixed. I checkout branch develop. There is no branch develop for the sub-repos, so what am I supposed to checkout, master, or some particular commit? I went with master. I do not understand a lot of CMake, but since it is a header-only library, I assume that I can just #include the file "include/boost/outcome.hpp", and my programs (compiled manually) should compile. But the only change in the commit that was supposed to fix the bug, was in a .cmake file, so I cannot see how it would help fix a header only library. Also, would the fix be visible in a "precompiled" header, or normal headres, or both? I am not complaining about this particular fix. I would like to know how in this system of mcros, sub-modules and preprocessed headers, I can figure out what changes will be observed in my program, when I see a particular change in git sub-repo. Regards, &rzej;
On 26/05/2017 15:14, Andrzej Krzemienski via Boost wrote:
The discussion mostly revolves around the design of the interface of `outcome::expected` and even `std::expected`. My questions here are about the way this library will be distributed to users. And I am uncomfortable with the situation. I am not necessarily saying it is wrong, but I do not understand what is going on here.
1. The current GitHub repository consists of sub-repos. Do you (Niall) plan to have it like this when the library is accepted? Is it relevant?
A lot of the opposition to git subrepos appears to stem from lack of awareness of how they and git work. Some are opposed to boost-lite substituting for Boost, but as I have mentioned a fair few times now, I am following precedent for C++ 14 mandatory libraries here which doesn't have a hard dependency on monolithic Boost, and whether the internal platform abstraction layer is in a subrepo or not isn't hugely important for the end user. I mean, they just #include and go. If that works, does any of the rest of it matter?
2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it controls whether I use this "preprocessed" file versus if I use... what? Normal header files? What is gained by this preprocessed file? Not having to include more than one header, or something else? Can I get different results when compiling with and without this macro?
The partially preprocessed edition is auto generated per commit. It saves the compiler from doing all the recursive #includes per compiland. It reduces compile times for end users a lot, I measured about half a second per compiland. Say for a project of 200 compilands, that's 10 seconds. Several other Boost libraries also pre-preprocess header files into the source tree and when you #include that library, you are including the pre-preprocessed edition, not the original source code. It's pretty conventional for libraries doing a lot preprocessor work to use this technique to reduce the compile time impact on end users.
3. I am recommended to use this macro BOOST_OUTCOME_V1_NAMESPACE. I am told it has something to do with ABI stability? Can you elaborate on how this guarantees ABI stability. Or is its purpose different?
It's described in the docs at https://ned14.github.io/boost.outcome/md_doc_md_02-tutorial_a.html#expected_... where it says: // Traditional: use SOME version Boost.Outcome visible to the compiler/linker namespace outcome = boost::outcome; // Better: use EXACTLY the Boost.Outcome visible in the current translation unit namespace outcome = BOOST_OUTCOME_V1_NAMESPACE; Imagine a future world where we supply two incompatible versions of Outcome: 1. namespace boost { namespace outcome { namespace v1 { ... } } } 2. namespace boost { namespace outcome { inline namespace v2 { ... } } } If you write: namespace outcome = boost::outcome; You are going to get the v2 namespace as that's the inlined latest version. Your code may now break because you wrote your code for v1. If you write instead: namespace outcome = BOOST_OUTCOME_V1_NAMESPACE; Then your code gets the v1 namespace it was written against. This design allows some code to use v1 and other code to use v2 in the same translation unit. This prevents dependency includes messing things up for other dependency includes.
I have a certain problem with understanding this philosophy. A couple of days back, I reported the compilation failure in MinGW. I can see that the issue (https://github.com/ned14/boost.outcome/issues/36) is reorted as fixed in branch 'develop'. I would like to confirm that the bug is fixed. I checkout branch develop. There is no branch develop for the sub-repos, so what am I supposed to checkout, master, or some particular commit? I went with master.
This is not the correct usage of git. In git to check out branch develop and the exact corresponding editions of subrepos for develop branch you would do: git checkout develop git submodule update --recursive This is 100% standard git when checking out a new branch. Nothing to do with Outcome.
I do not understand a lot of CMake, but since it is a header-only library, I assume that I can just #include the file "include/boost/outcome.hpp", and my programs (compiled manually) should compile.
Correct.
But the only change in the commit that was supposed to fix the bug, was in a .cmake file, so I cannot see how it would help fix a header only library.
You must have missed the missing #include I added.
Also, would the fix be visible in a "precompiled" header, or normal headres, or both?
The missing #include appears in the partially preprocessed edition as you would expect. The cmake changes were to fix other issues. I was forcing stack protector on if GCC was detected. Stack protector is not supported by mingw, so I no longer enable it for mingw only. I also added the ability to force disable clang-tidy as the mingw-w64 clang-tidy segfaults currently.
I am not complaining about this particular fix. I would like to know how in this system of mcros, sub-modules and preprocessed headers, I can figure out what changes will be observed in my program, when I see a particular change in git sub-repo.
Github usefully displays the exact changes, including in any subrepos. The display for the mingw bug fix can be found at: https://github.com/ned14/boost.outcome/commit/62d9bed841af5b2dfd85f17aa17a38... You'll see immediately at the top the files changed in any subrepos. Clicking on any of them will display a colour coded diff of before to after. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
2017-05-26 17:07 GMT+02:00 Niall Douglas via Boost
The discussion mostly revolves around the design of the interface of `outcome::expected` and even `std::expected`. My questions here are about the way this library will be distributed to users. And I am uncomfortable with the situation. I am not necessarily saying it is wrong, but I do not understand what is going on here.
1. The current GitHub repository consists of sub-repos. Do you (Niall)
On 26/05/2017 15:14, Andrzej Krzemienski via Boost wrote: plan
to have it like this when the library is accepted? Is it relevant?
A lot of the opposition to git subrepos appears to stem from lack of awareness of how they and git work. Some are opposed to boost-lite substituting for Boost, but as I have mentioned a fair few times now, I am following precedent for C++ 14 mandatory libraries here which doesn't have a hard dependency on monolithic Boost, and whether the internal platform abstraction layer is in a subrepo or not isn't hugely important for the end user.
Out of curiosity, what precedent is it?
I mean, they just #include and go. If that works, does any of the rest of it matter?
As a matter of fact, my questions were motivated by the fact that I #included but it didn't work. But apparrently, I incorrectly attributed the problem to sub-modules.
2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it controls whether I use this "preprocessed" file versus if I use... what? Normal header files? What is gained by this preprocessed file? Not having to include more than one header, or something else? Can I get different results when compiling with and without this macro?
The partially preprocessed edition is auto generated per commit. It saves the compiler from doing all the recursive #includes per compiland. It reduces compile times for end users a lot, I measured about half a second per compiland. Say for a project of 200 compilands, that's 10 seconds.
Are you saying the gain stems form includingg 1 versus N files?
Several other Boost libraries also pre-preprocess header files into the source tree and when you #include that library, you are including the pre-preprocessed edition, not the original source code. It's pretty conventional for libraries doing a lot preprocessor work to use this technique to reduce the compile time impact on end users.
Could you tell me which libraries? Also, if the contents are identical, what do I need the non-preprocessed version for?
3. I am recommended to use this macro BOOST_OUTCOME_V1_NAMESPACE. I am told it has something to do with ABI stability? Can you elaborate on how this guarantees ABI stability. Or is its purpose different?
It's described in the docs at https://ned14.github.io/boost.outcome/md_doc_md_02-tutorial_ a.html#expected_example where it says:
// Traditional: use SOME version Boost.Outcome visible to the compiler/linker namespace outcome = boost::outcome;
// Better: use EXACTLY the Boost.Outcome visible in the current translation unit namespace outcome = BOOST_OUTCOME_V1_NAMESPACE;
Imagine a future world where we supply two incompatible versions of Outcome:
1. namespace boost { namespace outcome { namespace v1 { ... } } }
2. namespace boost { namespace outcome { inline namespace v2 { ... } } }
If you write:
namespace outcome = boost::outcome;
You are going to get the v2 namespace as that's the inlined latest version. Your code may now break because you wrote your code for v1.
If you write instead:
namespace outcome = BOOST_OUTCOME_V1_NAMESPACE;
Then your code gets the v1 namespace it was written against.
This design allows some code to use v1 and other code to use v2 in the same translation unit. This prevents dependency includes messing things up for other dependency includes.
Ok, let me change your explanation a bit. Going back to your exable, I have two version namespaces: ``` namespace boost { namespace outcome { namespace v1 { ... } } } namespace boost { namespace outcome { inline namespace v2 { ... } } } ``` Now, if I want to use outcome from v1, I can type: ``` namespace outcome = boost::outcome::v1; ``` And I didn't use any macro. I guess my question is, why do you need a macro for it?
I have a certain problem with understanding this philosophy. A couple of days back, I reported the compilation failure in MinGW. I can see that the issue (https://github.com/ned14/boost.outcome/issues/36) is reorted as fixed in branch 'develop'. I would like to confirm that the bug is fixed. I checkout branch develop. There is no branch develop for the sub-repos, so what am I supposed to checkout, master, or some particular commit? I went with master.
This is not the correct usage of git.
In git to check out branch develop and the exact corresponding editions of subrepos for develop branch you would do:
git checkout develop git submodule update --recursive
Thanks. I was missing that.
This is 100% standard git when checking out a new branch. Nothing to do with Outcome.
I do not understand a lot of CMake, but since it is a header-only library, I assume that I can just #include the file "include/boost/outcome.hpp", and my programs (compiled manually) should compile.
Correct.
But the only change in the commit that was supposed to fix the bug, was in a .cmake file, so I cannot see how it would help fix a header only library.
You must have missed the missing #include I added.
Yes, I did: `
Also, would the fix be visible in a "precompiled" header, or normal headres, or both?
The missing #include appears in the partially preprocessed edition as you would expect.
The cmake changes were to fix other issues. I was forcing stack protector on if GCC was detected. Stack protector is not supported by mingw, so I no longer enable it for mingw only. I also added the ability to force disable clang-tidy as the mingw-w64 clang-tidy segfaults currently.
I am not complaining about this particular fix. I would like to know how in this system of mcros, sub-modules and preprocessed headers, I can figure out what changes will be observed in my program, when I see a particular change in git sub-repo.
Github usefully displays the exact changes, including in any subrepos. The display for the mingw bug fix can be found at:
https://github.com/ned14/boost.outcome/commit/ 62d9bed841af5b2dfd85f17aa17a3876d966cb74
You'll see immediately at the top the files changed in any subrepos. Clicking on any of them will display a colour coded diff of before to after.
Yes, I get that. Ok, now I understand why I got confused. I think the fix simply did not remove all errors on my version of MinGW. Regards, &rzej;
1. The current GitHub repository consists of sub-repos. Do you (Niall) plan to have it like this when the library is accepted? Is it relevant?
A lot of the opposition to git subrepos appears to stem from lack of awareness of how they and git work. Some are opposed to boost-lite substituting for Boost, but as I have mentioned a fair few times now, I am following precedent for C++ 14 mandatory libraries here which doesn't have a hard dependency on monolithic Boost, and whether the internal platform abstraction layer is in a subrepo or not isn't hugely important for the end user.
Out of curiosity, what precedent is it?
I believe Boost.Hana has no hard dependency on the rest of Boost. I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. I have asked them to say this publicly here, but I would assume they cannot for some reason or other. Quite a few talked about how their multinational's processes would find a standalone Boost.Outcome much much easier to deal with than one with dependency on other Boost libraries. Some of those are household name multinationals, and what they report matches my experience at BlackBerry.
I mean, they just #include and go. If that works, does any of the rest of it matter?
As a matter of fact, my questions were motivated by the fact that I #included but it didn't work. But apparrently, I incorrectly attributed the problem to sub-modules.
Mingw is not a regularly tested platform, and hence is not advertised on the documented compiler support page. Last time I tested it was well before Christmas. It's working on develop branch for me with my mingw-w64, but it's not for you with your version. Problems like these are exactly why I don't support mingw. People ought to use MSVC or winclang on Windows, those work much more reliably. If people really need a POSIX-y environment, Windows can now run Linux binaries very well, even from Win32.
2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it controls whether I use this "preprocessed" file versus if I use... what? Normal header files? What is gained by this preprocessed file? Not having to include more than one header, or something else? Can I get different results when compiling with and without this macro?
The partially preprocessed edition is auto generated per commit. It saves the compiler from doing all the recursive #includes per compiland. It reduces compile times for end users a lot, I measured about half a second per compiland. Say for a project of 200 compilands, that's 10 seconds.
Are you saying the gain stems form includingg 1 versus N files?
That's part of it. But avoiding all the recursive macro expansion certainly helps too.
Several other Boost libraries also pre-preprocess header files into the source tree and when you #include that library, you are including the pre-preprocessed edition, not the original source code. It's pretty conventional for libraries doing a lot preprocessor work to use this technique to reduce the compile time impact on end users.
Could you tell me which libraries?
Is it Boost.Geometry and Boost.Serialisation or something? Back in the day where we emulated variadic templates using preprocessor recursive includes, that's what I'm thinking of.
Also, if the contents are identical, what do I need the non-preprocessed version for?
Well, it's the source of the source as it were.
Ok, let me change your explanation a bit. Going back to your exable, I have two version namespaces:
``` namespace boost { namespace outcome { namespace v1 { ... } } } namespace boost { namespace outcome { inline namespace v2 { ... } } } ``` Now, if I want to use outcome from v1, I can type:
``` namespace outcome = boost::outcome::v1; ```
And I didn't use any macro. I guess my question is, why do you need a macro for it?
Whilst Outcome is in an unstable state, the actual namespace used is: namespace boost { namespace outcome { inline namespace v1_GITSHA { ... } } } So there is no boost::outcome::v1 namespace yet, but there will be one day. Hence the macro.
Yes, I get that. Ok, now I understand why I got confused. I think the fix simply did not remove all errors on my version of MinGW.
Yes, it's a mystery. I would assume that your mingw-w64 is older than mine. They may have since implemented the integer to string conversion routines the compile error is complaining about recently. If you can figure out a way of detecting mingw-w64 version, I can use the non-_s editions of those conversion functions. That would get you up and running on your version of mingw. It might be worth, to help you with your review, to try fixing your Outcome edition and send me a pull request to try out the bug reporting. You can either fix the partially preprocessed header, or dive in and fix the original boost-lite source if you compile your program with BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
2017-05-27 1:20 GMT+02:00 Niall Douglas via Boost
1. The current GitHub repository consists of sub-repos. Do you (Niall) plan to have it like this when the library is accepted? Is it relevant?
A lot of the opposition to git subrepos appears to stem from lack of awareness of how they and git work. Some are opposed to boost-lite substituting for Boost, but as I have mentioned a fair few times now, I am following precedent for C++ 14 mandatory libraries here which doesn't have a hard dependency on monolithic Boost, and whether the internal platform abstraction layer is in a subrepo or not isn't hugely important for the end user.
Out of curiosity, what precedent is it?
I believe Boost.Hana has no hard dependency on the rest of Boost.
Ok.
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. I have asked them to say this publicly here, but I would assume they cannot for some reason or other. Quite a few talked about how their multinational's processes would find a standalone Boost.Outcome much much easier to deal with than one with dependency on other Boost libraries. Some of those are household name multinationals, and what they report matches my experience at BlackBerry.
This probably deserves a separate thread. My understanding is that we have three expectations: 1. Boost developers do not want duplication in Boost. 2. Non-boost users of Outcome do not want a dependncy on Boost. 3. Niall does not want to maintain two nearly identical libraries.
I mean, they just #include and go. If that works, does any of the rest of it matter?
As a matter of fact, my questions were motivated by the fact that I #included but it didn't work. But apparrently, I incorrectly attributed the problem to sub-modules.
Mingw is not a regularly tested platform, and hence is not advertised on the documented compiler support page. Last time I tested it was well before Christmas.
Hold on. This is the page you are referring to: https://ned14.github.io/boost.outcome/prerequisites.html It says:
Outcome is a header only C++ 14 library known to work on these compilers or better:
- clang 3.5 (LLVM) - clang 3.7 (with Microsoft Codegen) - GCC 5.4 - VS2015 Update 2 - Xcode 7.3
It does not mention explicitly that it does not support MinGW. Now, MinGW, according to my knowledge, is not a compiler but a platform on which a compiler works. On MinGW I am using compiler GCC 6.3.0, and this compiler is supported (Or not? -- you are ony mentioning GCC 5.4). This has been always my understanding of what MinGW is.
It's working on develop branch for me with my mingw-w64, but it's not for you with your version. Problems like these are exactly why I don't support mingw. People ought to use MSVC or winclang on Windows, those work much more reliably. If people really need a POSIX-y environment, Windows can now run Linux binaries very well, even from Win32.
Your decision to simply refuse to support some platform, well.., bothers me. I understand that you do not have access to different compier/platform versions, and that makes looking for bugs quite a burden. But it was my understanding that this is how library maintainance works in Boost. You have the test matrix, where people offer to test your library on compilers/platforms you have never thought of, and you get the required feedback. Can you be persuaded to a conditional agreement: if Outcome gets accepted into Boost, you extend the range of supported compilers.
2. This macro BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE, it controls whether I use this "preprocessed" file versus if I use... what? Normal header files? What is gained by this preprocessed file? Not having to include more than one header, or something else? Can I get different results when compiling with and without this macro?
The partially preprocessed edition is auto generated per commit. It saves the compiler from doing all the recursive #includes per compiland. It reduces compile times for end users a lot, I measured about half a second per compiland. Say for a project of 200 compilands, that's 10 seconds.
Are you saying the gain stems form includingg 1 versus N files?
That's part of it. But avoiding all the recursive macro expansion certainly helps too.
Macros other than #include ? Usually you need macros to do things in a different way based on platform, but the precompiled heder does not know what platform it will be used on, so I wonder what macros you mean.
Several other Boost libraries also pre-preprocess header files into the source tree and when you #include that library, you are including the pre-preprocessed edition, not the original source code. It's pretty conventional for libraries doing a lot preprocessor work to use this technique to reduce the compile time impact on end users.
Could you tell me which libraries?
Is it Boost.Geometry and Boost.Serialisation or something? Back in the day where we emulated variadic templates using preprocessor recursive includes, that's what I'm thinking of.
Ok.
Also, if the contents are identical, what do I need the non-preprocessed version for?
Well, it's the source of the source as it were.
Ok.
Ok, let me change your explanation a bit. Going back to your exable, I have two version namespaces:
``` namespace boost { namespace outcome { namespace v1 { ... } } } namespace boost { namespace outcome { inline namespace v2 { ... } } } ``` Now, if I want to use outcome from v1, I can type:
``` namespace outcome = boost::outcome::v1; ```
And I didn't use any macro. I guess my question is, why do you need a macro for it?
Whilst Outcome is in an unstable state, the actual namespace used is:
namespace boost { namespace outcome { inline namespace v1_GITSHA { ... } } }
This sounds like we are doing a formal review of a library in an unstable state.
So there is no boost::outcome::v1 namespace yet, but there will be one day. Hence the macro.
Will that day be before Outcome enters Boost? IOW, can I expect that in an official Boost version I will be able to just use: `boost::outcome::v1`?
Yes, I get that. Ok, now I understand why I got confused. I think the fix simply did not remove all errors on my version of MinGW.
Yes, it's a mystery. I would assume that your mingw-w64 is older than mine. They may have since implemented the integer to string conversion routines the compile error is complaining about recently.
Maybe. On the other hand my bug is about using undeclared symbols ` _ui64toa_s
If you can figure out a way of detecting mingw-w64 version, I can use the non-_s editions of those conversion functions. That would get you up and running on your version of mingw.
It might be worth, to help you with your review, to try fixing your Outcome edition and send me a pull request to try out the bug reporting. You can either fix the partially preprocessed header, or dive in and fix the original boost-lite source if you compile your program with BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE.
Niall
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost
Yes, I get that. Ok, now I understand why I got confused. I think the fix
simply did not remove all errors on my version of MinGW.
Yes, it's a mystery. I would assume that your mingw-w64 is older than mine. They may have since implemented the integer to string conversion routines the compile error is complaining about recently.
Sorry, the mail got sent prematurely. I was saying: The bug is caused by symbols `_ui64toa_s` and `_itoa_s` being used but not declared. Do you need platform-specific things for accomplishing your task? Are there no C++-standard ways of converting integers to string that would work for you?
If you can figure out a way of detecting mingw-w64 version, I can use the non-_s editions of those conversion functions. That would get you up and running on your version of mingw.
Ok, I'll look for it. You mean how to tell a 64 versus non-64 version of minGW, right?
It might be worth, to help you with your review, to try fixing your Outcome edition and send me a pull request to try out the bug reporting. You can either fix the partially preprocessed header, or dive in and fix the original boost-lite source if you compile your program with BOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE.
Ok. Regards, &rzej;
Yes, it's a mystery. I would assume that your mingw-w64 is older than mine. They may have since implemented the integer to string conversion routines the compile error is complaining about recently.
The bug is caused by symbols `_ui64toa_s` and `_itoa_s` being used but not declared. Do you need platform-specific things for accomplishing your task? Are there no C++-standard ways of converting integers to string that would work for you?
The compiler errors you sent me said that they weren't declared in scope. Not undefined reference. Likely your mingw-w64 headers are incomplete. Remember that file is C code, not C++ code, and it's Windows-only, so the choice of number to string function is more limited. Using itoa() directly is frowned upon by MSVC with warnings, so I used itoa_s() to shut it up. Fixing your compile error would be extremely trivial, we just need a way of selecting itoa() vs itoa_s().
If you can figure out a way of detecting mingw-w64 version, I can use the non-_s editions of those conversion functions. That would get you up and running on your version of mingw.
Ok, I'll look for it. You mean how to tell a 64 versus non-64 version of minGW, right?
I'd even accept #ifdef __MINGW_W64__ or whatever its macro is. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Remember that file is C code, not C++ code, and it's Windows-only, so the choice of number to string function is more limited.
The standard C function for number-to-string is sprintf.
I believe it may allocate memory. itoa() may not, which is important for signal handlers. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. I have asked them to say this publicly here, but I would assume they cannot for some reason or other. Quite a few talked about how their multinational's processes would find a standalone Boost.Outcome much much easier to deal with than one with dependency on other Boost libraries. Some of those are household name multinationals, and what they report matches my experience at BlackBerry.
This probably deserves a separate thread. My understanding is that we have three expectations:
1. Boost developers do not want duplication in Boost.
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes. I don't know about not wanting duplication in Boost. There is a ton of duplication in Boost. It's been waved through in peer review many times in the past.
2. Non-boost users of Outcome do not want a dependncy on Boost.
Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
3. Niall does not want to maintain two nearly identical libraries.
I still hold open the offer of a fully Boost flavoured edition of Outcome. I think it a mistake personally, but the offer is there. I've given up on trying to instil awareness of the end user experience of Boost into people on boost-dev.
Mingw is not a regularly tested platform, and hence is not advertised on the documented compiler support page. Last time I tested it was well before Christmas.
Hold on. This is the page you are referring to: https://ned14.github.io/boost.outcome/prerequisites.html
It says:
Outcome is a header only C++ 14 library known to work on these compilers or better:
- clang 3.5 (LLVM) - clang 3.7 (with Microsoft Codegen) - GCC 5.4 - VS2015 Update 2 - Xcode 7.3
It does not mention explicitly that it does not support MinGW. Now, MinGW, according to my knowledge, is not a compiler but a platform on which a compiler works. On MinGW I am using compiler GCC 6.3.0, and this compiler is supported (Or not? -- you are ony mentioning GCC 5.4). This has been always my understanding of what MinGW is.
That's a very fair observation. I have updated develop branch to indicate what compiler-platform combos meant.
It's working on develop branch for me with my mingw-w64, but it's not for you with your version. Problems like these are exactly why I don't support mingw. People ought to use MSVC or winclang on Windows, those work much more reliably. If people really need a POSIX-y environment, Windows can now run Linux binaries very well, even from Win32.
Your decision to simply refuse to support some platform, well.., bothers me. I understand that you do not have access to different compier/platform versions, and that makes looking for bugs quite a burden. But it was my understanding that this is how library maintainance works in Boost. You have the test matrix, where people offer to test your library on compilers/platforms you have never thought of, and you get the required feedback. Can you be persuaded to a conditional agreement: if Outcome gets accepted into Boost, you extend the range of supported compilers.
It costs time and money to support platforms you don't personally use, and I have found an eager approach to deprecating and desupporting open source code I no longer personally use to be the only viable approach for my very limited free time. Once you're been supplying open source to people for twenty years as I have, it's the only feasible attitude to take. It also lets end users either move on to alternatives instead of being strung along waiting for fixes to software I won't be regularly updating any more, or else employ me to fix things for them if their need is urgent. I aim to support the most common 98% of users in my open source. If others wish to maintain my code on their niche platform/compiler/architecture, I will accept patches from them maintaining that support, and I'll try not to gratuitously break their contributed code. But I won't be doing it myself. I think supporting the top 98% of the most common environments is more than plenty. And I would add that Boost libraries only need to demonstrate a portability requirement. That falls very far short of endless and permanent support of niche, and often broken, toolchains.
Macros other than #include ? Usually you need macros to do things in a different way based on platform, but the precompiled heder does not know what platform it will be used on, so I wonder what macros you mean.
Quite a bit of code is auto generated using preprocessor metaprogramming. All the ABI and namespace versioning stuff, for example. The partial preprocess step executes all the metaprogramming at build time and I commit to git an expanded edition without the preprocessor metaprogramming. When you #include Outcome, your compiler only needs to preprocess platform specific #if branches. It is very little work to do, and hence runs about a half second quicker.
Whilst Outcome is in an unstable state, the actual namespace used is:
namespace boost { namespace outcome { inline namespace v1_GITSHA { ... } } }
This sounds like we are doing a formal review of a library in an unstable state.
Ok, unstable ABI then. Right now I am not promising the ABI won't change. When I do promise that the ABI is written permanently into stone, you'll get your boost::outcome::v1 namespace, and per commit it'll be checked for breaking changes by the abi-compliance-checker. That way end users, who will tend to return outcomes a lot from public extern functions, will know for a fact that upgrading Outcome does not force a complete rebuild of all shared libraries. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
2017-05-27 16:40 GMT+02:00 Niall Douglas via Boost
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. I have asked them to say this publicly here, but I would assume they cannot for some reason or other. Quite a few talked about how their multinational's processes would find a standalone Boost.Outcome much much easier to deal with than one with dependency on other Boost libraries. Some of those are household name multinationals, and what they report matches my experience at BlackBerry.
This probably deserves a separate thread. My understanding is that we have three expectations:
1. Boost developers do not want duplication in Boost.
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
I don't know about not wanting duplication in Boost. There is a ton of duplication in Boost. It's been waved through in peer review many times in the past.
2. Non-boost users of Outcome do not want a dependncy on Boost.
Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
3. Niall does not want to maintain two nearly identical libraries.
I still hold open the offer of a fully Boost flavoured edition of Outcome. I think it a mistake personally, but the offer is there. I've given up on trying to instil awareness of the end user experience of Boost into people on boost-dev.
Mingw is not a regularly tested platform, and hence is not advertised on the documented compiler support page. Last time I tested it was well before Christmas.
Hold on. This is the page you are referring to: https://ned14.github.io/boost.outcome/prerequisites.html
It says:
Outcome is a header only C++ 14 library known to work on these compilers or better:
- clang 3.5 (LLVM) - clang 3.7 (with Microsoft Codegen) - GCC 5.4 - VS2015 Update 2 - Xcode 7.3
It does not mention explicitly that it does not support MinGW. Now, MinGW, according to my knowledge, is not a compiler but a platform on which a compiler works. On MinGW I am using compiler GCC 6.3.0, and this compiler is supported (Or not? -- you are ony mentioning GCC 5.4). This has been always my understanding of what MinGW is.
That's a very fair observation. I have updated develop branch to indicate what compiler-platform combos meant.
It's working on develop branch for me with my mingw-w64, but it's not for you with your version. Problems like these are exactly why I don't support mingw. People ought to use MSVC or winclang on Windows, those work much more reliably. If people really need a POSIX-y environment, Windows can now run Linux binaries very well, even from Win32.
Your decision to simply refuse to support some platform, well.., bothers me. I understand that you do not have access to different compier/platform versions, and that makes looking for bugs quite a burden. But it was my understanding that this is how library maintainance works in Boost. You have the test matrix, where people offer to test your library on compilers/platforms you have never thought of, and you get the required feedback. Can you be persuaded to a conditional agreement: if Outcome gets accepted into Boost, you extend the range of supported compilers.
It costs time and money to support platforms you don't personally use, and I have found an eager approach to deprecating and desupporting open source code I no longer personally use to be the only viable approach for my very limited free time. Once you're been supplying open source to people for twenty years as I have, it's the only feasible attitude to take. It also lets end users either move on to alternatives instead of being strung along waiting for fixes to software I won't be regularly updating any more, or else employ me to fix things for them if their need is urgent.
I aim to support the most common 98% of users in my open source. If others wish to maintain my code on their niche platform/compiler/architecture, I will accept patches from them maintaining that support, and I'll try not to gratuitously break their contributed code. But I won't be doing it myself. I think supporting the top 98% of the most common environments is more than plenty.
That sounds fair.
And I would add that Boost libraries only need to demonstrate a portability requirement. That falls very far short of endless and permanent support of niche, and often broken, toolchains.
Macros other than #include ? Usually you need macros to do things in a different way based on platform, but the precompiled heder does not know what platform it will be used on, so I wonder what macros you mean.
Quite a bit of code is auto generated using preprocessor metaprogramming. All the ABI and namespace versioning stuff, for example.
The partial preprocess step executes all the metaprogramming at build time and I commit to git an expanded edition without the preprocessor metaprogramming. When you #include Outcome, your compiler only needs to preprocess platform specific #if branches. It is very little work to do, and hence runs about a half second quicker.
Whilst Outcome is in an unstable state, the actual namespace used is:
namespace boost { namespace outcome { inline namespace v1_GITSHA { ... } } }
This sounds like we are doing a formal review of a library in an unstable state.
Ok, unstable ABI then. Right now I am not promising the ABI won't change. When I do promise that the ABI is written permanently into stone, you'll get your boost::outcome::v1 namespace, and per commit it'll be checked for breaking changes by the abi-compliance-checker.
Will you stabilise v1 in the first official release of official Boost.Outcome. Or in other words, my expectation is that when I download the official Boost release I will be using `boost::outcome::v1`. Do you commit to this?
That way end users, who will tend to return outcomes a lot from public extern functions, will know for a fact that upgrading Outcome does not force a complete rebuild of all shared libraries.
Ok, unstable ABI then. Right now I am not promising the ABI won't change. When I do promise that the ABI is written permanently into stone, you'll get your boost::outcome::v1 namespace, and per commit it'll be checked for breaking changes by the abi-compliance-checker.
Will you stabilise v1 in the first official release of official Boost.Outcome. Or in other words, my expectation is that when I download the official Boost release I will be using `boost::outcome::v1`. Do you commit to this?
If accepted, I'd do one Boost release with the unstable ABI, and collect in bug fixes, changes etc. If there were a lot of fixes, I'd do another Boost release until the bug reports became minimal. Then I'd hard code v1 ABI in stone, and it would not change again in the future. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On Sat, May 27, 2017 at 7:40 AM, Niall Douglas wrote:
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. [snip] Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
It seems like these users are best satisfied with just github.com/ned14/outcome. i.e. They wouldn't even need Outcome to be part of the Boost collection of libraries, if they desire Outcome to be standalone and independent of Boost. Meanwhile, those Boost users who do have some expectation or desire that libraries included in the Boost distribution benefit from all the work done in other libraries (e.g. compiler workarunds, compiler feature detection), or simply not duplicate code that another Boost library has an optimal implementation of, would have different expectations of a "Boost" Outcome. Glen
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. [snip] Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
It seems like these users are best satisfied with just github.com/ned14/outcome. i.e. They wouldn't even need Outcome to be part of the Boost collection of libraries, if they desire Outcome to be standalone and independent of Boost.
That's not what I've been told. They want Boost libraries without all the hassle that comes with Boost libraries. I keep saying this for years, but no one here on boost-dev appears to listen.
Meanwhile, those Boost users who do have some expectation or desire that libraries included in the Boost distribution benefit from all the work done in other libraries (e.g. compiler workarunds, compiler feature detection), or simply not duplicate code that another Boost library has an optimal implementation of, would have different expectations of a "Boost" Outcome.
The customisation points are available for any end user to change a minimum default implementation provided by Outcome to any other implementation, including a Boost implementation. I think that a perfectly fine situation if it avoids a hard Boost dependency, it's not like anybody is losing out here. In numbers terms, far more people have asked for Outcome to remain free of a Boost dependency than the relatively few here on boost-dev. As with all the other changes I've agreed to, I'm following the numbers, if a clear majority want something, I try to provide it if I can. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On Sat, May 27, 2017 at 5:47 PM, Niall Douglas via Boost wrote:
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. [snip] Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
It seems like these users are best satisfied with just github.com/ned14/outcome. i.e. They wouldn't even need Outcome to be part of the Boost collection of libraries, if they desire Outcome to be standalone and independent of Boost.
That's not what I've been told.
They want Boost libraries without all the hassle that comes with Boost libraries. I keep saying this for years, but no one here on boost-dev appears to listen.
They're telling you they want a Boost release to contain your Outcome library, but that they only want to depend on your Outcome library and nothing else in Boost? Why wouldn't they prefer to download a 1 MB outcome.zip from github/ned14 instead of a 150 MB Boost release zip? Glen
That's not what I've been told.
They want Boost libraries without all the hassle that comes with Boost libraries. I keep saying this for years, but no one here on boost-dev appears to listen.
They're telling you they want a Boost release to contain your Outcome library, but that they only want to depend on your Outcome library and nothing else in Boost?
Yes.
Why wouldn't they prefer to download a 1 MB outcome.zip from github/ned14 instead of a 150 MB Boost release zip?
I don't think anyone worries about a few hundred megabytes of download any more. I think it's much more to do with hassle to use a Boost library, or rather, lack of hassle. Where hassle is defined very broadly, including legal approval, integration into local build and test, source auditing, symbol collision, and so on. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Niall Douglas wrote:
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
Saying that is a good indicator that you simply don't understand the objections, so you label them irrational. Take for example the preprocessed outcome_v1_0.hpp header. You think that the objection is that it's preprocessed. Not in the slightest. The objection is that the non-preprocessed form, which is more convenient when one needs to look at the implementation, study how it's organized, fix a problem one's having (on mignw64, for instance), then prepare a pull request, does not compile unless one has a foreign submodule installed, which in turn picks up two more, even more foreign, submodules. It's not possible to have foreign submodules in a Boost distribution, so the choice there would be to either not provide the non-preprocessed form at all, or provide it in a non-functional form. In addition, having the preprocessed form automatically generated from whatever's needed from boost-lite (1) obscures which specific parts of boost-lite are used and (2) makes it possible for later versions to pick up other parts of boost-lite. The objection - no, the requirement for acceptance - here is not "do not generate a preprocessed form of Outcome." The requirement is that everything necessary for Outcome to compile and work in non-preprocessed form should be part of the Outcome directory in $BOOST_ROOT/libs/outcome, without any foreign repositories being incorporated there by reference. That is, outcome.hpp in the Boost distro should compile and work in non-preprocessed form. This - makes it possible to follow the implementation in non-obscured form, - makes it immediately visible what Outcome's implementation detail dependencies are, - makes it possible for people to fix issues in Outcome and give you pull requests against the input from which the preprocessed form is generated, rather than patching the preprocessed header, - avoids potential copyright/license issues with incorporating foreign (non-boostorg) code via a script
Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
Yes, and I already answered it, with your swiftly proceeding to ignore my answer. Probably because you didn't understand it, which of course means it's irrational. To repeat, it's not possible for a Boost user to not want a dependency on Boost. A Boost user already has Boost. This is tautological. Not wanting a dependency on "Boost" is characteristic for people who want to use a specific Boost library without any of the rest. This is not the same thing, and it does not at all describe all Boost users, so taking this (existing and legitimate) subset and talking about them as Boost **users** is simply disingenuous. You might note that I'm not one who is a fan of intra-Boost dependencies. You also might recall that I led an effort to eradicate many of the unnecessary ones, have often expressed an opinion that Boost should move in a direction of being less monolithic, and have done quite a bit of work to that effect. Nevertheless, things are what they are, and misrepresenting the actually existing state of affairs does not do service to anyone. The fact remains that (a) close integration between Boost libraries has its benefits to users and (b) a substantial portion of Boost users are not bothered by the downsides of this integration. By all means make Outcome independent of any other Boost libraries - depending on any isn't a requirement for acceptance, and many Boost libraries do try to be reasonably self-contained (*) - but do recognize that this move is not unquestionably without downsides. (*) At one point in the past - the not very recent past - I had shared_ptr.hpp compiling with an empty boost/config.hpp, because there was significant demand from people to use it without anything else from Boost. This demand subsided rapidly however once Boost took off. Nowadays, the majority of Boost users do have Boost.
Am 27.05.2017 um 18:08 schrieb Peter Dimov via Boost:
Niall Douglas wrote:
[snip]
Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
Yes, and I already answered it, with your swiftly proceeding to ignore my answer. Probably because you didn't understand it, which of course means it's irrational.
To repeat, it's not possible for a Boost user to not want a dependency on Boost. A Boost user already has Boost. This is tautological.
Not wanting a dependency on "Boost" is characteristic for people who want to use a specific Boost library without any of the rest. This is not the same thing, and it does not at all describe all Boost users, so taking this (existing and legitimate) subset and talking about them as Boost **users** is simply disingenuous.
Maybe I can step in here as a Boost user who prefers to not have too many inter-Boost dependencies between the different Boost-libraries. From my point of view, I am fine with having the entire Boost collection available for my source, even though I would prefer a less monolithic distribution. However, I would sometimes wish that some inter-boost dependencies would not exist or at least be not available in some certain situations. For example, in our code-base at work we have compilers supporting C++11 as a minimum and are already switching to C++14 as our base-level. Therefore we do not need any boost-provided classes that are already in the standard as e.g. Boost.SmartPtr, Boost.Move or Boost.Thread (although the latter supports some more functionality that we do not have in standard threads but which we are also not needing). If they can co-exist with the standard-versions that is ok but we would feel it would be better to get rid of them in such situations. Another thing, that has big impact on our code-base is Boost.MPL. We are using Boost.MSM which itself uses Boost.MPL. And we had to extend the preprocessed MPL-containers to support more than the standard 50 elements, because the state-machine built with Boost.MSM did require that. That however has impact on all other libraries that are using Boost.MPL, too. For example Boost.Flyweight and Boost.Multi_Index, which in our case do not need so many elements. Therefore their types consist mostly of mpl_::na which again results in very long type-names, so that some external tools (Valgrind.Massif comes to mind) cannot show the actual function-signature, because its internal type-name buffer gets filled with mpl_::nas. (Additionally, this might increase compile-times, too, although I did not measure that.) Would there be no dependency of Boost.Flyweight on Boost.MPL this might have been easier for us. But I cannot tell, if it would have been feasible to "reinvent" the required Boost.MPL parts without having a dependency on it. To get back to Outcome, I would recommend that is uses Boost.Config instead of a custom version of it because it seems to be quite useful, well tested and does not introduce many other inter-boost dependencies (as fas as I know). However, dependencies to other Boost.Libraries might be less helpful because maybe just some small part might be required and instead one gets dependencies to a whole lot of other Boost-libraries which are unnecessary. (You notice that I do not know really know which other dependencies there might be. I just wanted to explain the point of such Boost users who like the dependency-tree to be quite clean.) Just my 2ct. Deniz
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
Saying that is a good indicator that you simply don't understand the objections, so you label them irrational.
It's actually not about objections. It's about ignorance of how the C++ world has moved on since C++ 11 landed. Some here don't care that the C++ world is now overwhelmingly cmake based, and tight coupling into a huge monolith of unnecessary library dependency is just not acceptable for a modern C++ 11 or 14 library.
Take for example the preprocessed outcome_v1_0.hpp header. You think that the objection is that it's preprocessed. Not in the slightest.
The objection is that the non-preprocessed form, which is more convenient when one needs to look at the implementation, study how it's organized, fix a problem one's having (on mignw64, for instance), then prepare a pull request, does not compile unless one has a foreign submodule installed, which in turn picks up two more, even more foreign, submodules.
Most of the world using git has no problems with git submodules. The continuing refusal by some here to invest the effort in understanding modern tooling, and instead blame that tooling for not working the way they'd prefer, is the real source of objection. Away from here in the wider C++ world, nobody appears to have any problem forming a pull request on github which modifies a submodule. It's simply not a problem elsewhere.
In addition, having the preprocessed form automatically generated from whatever's needed from boost-lite (1) obscures which specific parts of boost-lite are used and (2) makes it possible for later versions to pick up other parts of boost-lite.
The partially preprocessed edition reduces compile times for end users. It can be disabled easily using a macro. End users don't care how the internals hang together. They do care about reduced compile times.
The objection - no, the requirement for acceptance - here is not "do not generate a preprocessed form of Outcome." The requirement is that everything necessary for Outcome to compile and work in non-preprocessed form should be part of the Outcome directory in $BOOST_ROOT/libs/outcome, without any foreign repositories being incorporated there by reference.
There is no such requirement for acceptance. Internal standalone utility libraries have a long history in Boost. If their use doesn't affect the end user experience, the choice to use internal standalone libraries is not relevant for acceptance.
That is, outcome.hpp in the Boost distro should compile and work in non-preprocessed form.
It does work in non-preprocessed form. Just update the git submodules after checkout as the git documentation itself tells you to do, and everybody should be doing after a git checkout anyway for any project. If people use git as git is documented, Outcome works perfectly fine in non-preprocessed form. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Niall Douglas wrote:
Most of the world using git has no problems with git submodules.
You just don't listen, do you? You can't have git submodules in a Boost distribution. It's an archive.
The partially preprocessed edition reduces compile times for end users.
You don't listen, do you? The objection is not against having a preprocessed edition. Have it. There's no problem with it.
There is no such requirement for acceptance. Internal standalone utility libraries have a long history in Boost.
Not listening, are we? Internal standalone utility libraries have a long history in Boost, as long as they are completely contained within their libs/$library directory. Once again, you can't have a git submodule in a Boost distribution, which is an archive. I give up. You're hopeless.
On 5/27/17 3:03 PM, Niall Douglas via Boost wrote:
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
Boost developers are attached to the current way of doing things. But it's not irrational. Boost libraries are source code. The do not (or should not) depend on build tools, the particular compiler, the operating system or whatever. They might depend on other source code libraries - boost or std. There is a wide combination of build environments which can incorporate this source code. If they follow C++ rules the boost source code can be incorporated into the build. Now it looks like you've injected a dependency going in the other direction - that the usage of outcome is dependent upon CMake, Git, Git submodules. Note that this is dependent upon the original dependencies of outcome on other boost libraries. The fact that these dependencies are masked by pre-processing just hides this fact. In boost, if an error is detected in config.hpp (for example) any other module which depends upon it needs to be re-built this can be done locally if desired. That's all. In your world the the preprocessing has to be redone so the user then rebuilt. So the "user" will need the original config.hpp anyway. Of course this applies to boost module which has been "imported" into outcome. If outcome has made it's own substitutes from scratch - like in the case of config.hpp - the situation is worse, the maintainer will have to maintain something that is repeated in boost. More work to do. Since we've now coupled the two tasks in both directions, they have to be handled as a pair. If other libraries were to adopt this approach it would be maintenance nightmare. Just the fact that that it depends on bunch of convoluted (git and submodules) and flakey (CMake) tools should be a tip off. I could go on but it's clear I'm not going to convince you this is a bad idea. I get that. But your major blunder is to try to tail gate a whole new way of doing things which was bound to be controversial into boost by attaching to an otherwise simple and perhaps useful facility. It's a pity since with a different approach you might have gotten more credibility and success. Your idea of addressing the issue of distributing minimal subset of boost related to a particular library (or set of libraries) doesn't belong here. It's unrelated to outcome, it's a boost-wide issue - not an issue with outcome. By conflating these issues and coupling it with your code you've made it almost impossible to get any useful part of the library accepted. And it's not because boost developers are ignorant of modern C++. That's just wishful thinking on your part. It's on you because you bad decisions. Robert Ramey
On 28/05/2017 00:04, Robert Ramey via Boost wrote:
On 5/27/17 3:03 PM, Niall Douglas via Boost wrote:
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
Boost developers are attached to the current way of doing things. But it's not irrational.
Boost libraries are source code. The do not (or should not) depend on build tools, the particular compiler, the operating system or whatever. They might depend on other source code libraries - boost or std.
There is a wide combination of build environments which can incorporate this source code. If they follow C++ rules the boost source code can be incorporated into the build.
Now it looks like you've injected a dependency going in the other direction - that the usage of outcome is dependent upon CMake, Git, Git submodules.
I have repeated myself several times now on this. End users can include the outcome header and get to work. No cmake, git, or anything else.
Note that this is dependent upon the original dependencies of outcome on other boost libraries. The fact that these dependencies are masked by pre-processing just hides this fact. In boost, if an error is detected in config.hpp (for example) any other module which depends upon it needs to be re-built this can be done locally if desired. That's all. In your world the the preprocessing has to be redone so the user then rebuilt. So the "user" will need the original config.hpp anyway.
I agreed well into last week to replace the extensive preprocessor metaprogramming with a template based solution. I don't see why people are still going on about this. I heard that people don't like the preprocessor work. I agreed to replace it. It's no longer a thing.
Of course this applies to boost module which has been "imported" into outcome. If outcome has made it's own substitutes from scratch - like in the case of config.hpp - the situation is worse, the maintainer will have to maintain something that is repeated in boost. More work to do. Since we've now coupled the two tasks in both directions, they have to be handled as a pair. If other libraries were to adopt this approach it would be maintenance nightmare. Just the fact that that it depends on bunch of convoluted (git and submodules) and flakey (CMake) tools should be a tip off.
I could go on but it's clear I'm not going to convince you this is a bad idea. I get that.
But your major blunder is to try to tail gate a whole new way of doing things which was bound to be controversial into boost by attaching to an otherwise simple and perhaps useful facility. It's a pity since with a different approach you might have gotten more credibility and success. Your idea of addressing the issue of distributing minimal subset of boost related to a particular library (or set of libraries) doesn't belong here. It's unrelated to outcome, it's a boost-wide issue - not an issue with outcome. By conflating these issues and coupling it with your code you've made it almost impossible to get any useful part of the library accepted.
And it's not because boost developers are ignorant of modern C++. That's just wishful thinking on your part. It's on you because you bad decisions.
Well, an ad hominem attack had to happen at some point. Let me firstly defend boost-lite, or rather the common support code currently called boost-lite but will be renamed at some point. It is quite frankly an amazing solution to the common framework and support needs of C++ 14 libraries. It lets new library authors get up and running with a new library very quickly, implementing best current practice build, packaging, test, dashboarding, version management and lots more without library developers having to think about any of that. It is free of legacy baggage, and saves me on a daily basis a ton load of time and hassle even amongst the three of my libraries it is used in. It also can scale out to an arbitrarily high number of libraries in a decentralised collection, far more incidentally than Boost could ever dream of precisely because of its decentralised design. I am proud of its design, the fact it confounds so many experts who study how it works is testament to the breath of fresh air it bring to modern C++ library design. I don't claim it to be perfect, it suffers particularly from immaturity, and hence I don't recommend that anyone else use it yet. But rather than attack it because it's different, you really should study it and learn from it because it has a lot of really great ideas and implementation in there. It could become the base of a major leap forward in standards aspiring C++ 14 and C++ 17 libraries precisely because we can finally dispense with the whole "one code silo to rule them all" philosophy. But let's return now to Outcome, as that's what this review is about. What happens if Outcome is accepted into Boost in a non-Boost flavoured form, as indeed it has been presented for review? I have already covered this in this review before, but let me repeat one solution of many possible: 1. boost-lite is an excellent neighbour to all other C++ libraries, including different versions of itself. It is benign to include into any translation unit under any circumstances. 2. As Outcome was accepted in std-flavoured form, I would eliminate the namespace bind technology from boost-lite to allow switching between the C++ 11 STL and the Boost STL. I would have deleted it last year except that I wasn't sure if you guys would demand a Boost flavoured library or not. 3. If the Boost release and package managers felt that git sub-submodule support was not going to be allowed, I would use __has_include (which works on all the compilers Outcome works on) to have Outcome probe for a checked out internal edition of the boost-lite git submodule. If not found, it would fall back to Boost.Config, Boost.Stacktrace etc for those parts, and rely on a local copy of some boost-lite support files for the rest. 4. I now have a single git repo which works well standalone and within Boost. I am happy, Boost is happy, Boost users are happy. Let's all dance. As I have said repeatedly during this week, these are all packaging and process problems. They are inconsequential to acceptance or rejection of this library. I am sorry you don't see it that way Robert, but quite frankly, your opinion has no technical basis in fact. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 5/28/17 4:29 AM, Niall Douglas via Boost wrote:
On 28/05/2017 00:04, Robert Ramey via Boost wrote:
And it's not because boost developers are ignorant of modern C++. That's just wishful thinking on your part. It's on you because you bad decisions.
Well, an ad hominem attack had to happen at some point.
This is not an ad hominem attack. I'm criticizing your choices. You've asserted that those objecting to your choices are ignorant of modern C++. You've asserted that "Some Boost developers are ideologically and irrationally attached to "how things are done around here". I dispute all of the above assertions. There is not evidence for them - how could there be as they are not true? And even if they were true, they would in no way be an argument for the library, up ending boost via the inclusion of a single very small and simple library or anything else. You've used these assertions as a way to discredit the arguments of those whom you disagree. This is wrong. Worse, it is contrary to your own interests. Many of us want you to succeed as we want many to succeed. Many of us much appreciate your efforts to contribute to boost, boost-gsoc, conferences etc., even though we disagree with most of your ideas. Many of us have tried to be constructive in attempts to make outcome a useful addition to boost. Assertions such as the above diminish this reservoir of good will. It is not to your advantage to do this.
Let me firstly defend boost-lite, or rather the common support code currently called boost-lite but will be renamed at some point. It is quite frankly an amazing solution to the common framework and support needs of C++ 14 libraries. This is an assertion that many of us question
But this was not my point or main concern. It was that this is out of scope for a boost library to change boost in this way. This is attempt to inject into boost a whole new way of doing things which many us don't have any faith in. It touches on our usage of Git, CMake, and other tools which are questions which are orthogonal to the acceptance of the outcome library. It lets new library authors get up and
running with a new library very quickly, implementing best current practice build, packaging, test, dashboarding, version management and lots more without library developers having to think about any of that.
Again - Looking that documentation and code I fail to be convinced of that.
It is free of legacy baggage, and saves me on a daily basis a ton load of time and hassle even amongst the three of my libraries it is used in. It also can scale out to an arbitrarily high number of libraries in a decentralised collection, far more incidentally than Boost could ever dream of precisely because of its decentralised design. I am proud of its design, the fact it confounds so many experts who study how it works is testament to the breath of fresh air it bring to modern C++ library design. I don't claim it to be perfect, it suffers particularly from immaturity, and hence I don't recommend that anyone else use it yet. But rather than attack it because it's different, you really should study it and learn from it because it has a lot of really great ideas and implementation in there. It could become the base of a major leap forward in standards aspiring C++ 14 and C++ 17 libraries precisely because we can finally dispense with the whole "one code silo to rule them all" philosophy.
Right. I think this demonstrates my point. We're not reviewing the source code of outcome here. You're advocating a replacing boost with something better. OK - but this it out of scope for the review of output.
But let's return now to Outcome, as that's what this review is about.
<snip>
Robert, but quite frankly, your opinion has no technical basis in fact.
LOL Right. It IS an opinion not a fact. That's why we're having the argument. Of course I would disagree that my arguments how no technical basis and you are free to so characterize them, but I'm doubtful it helps you in anyway. Although it's implicit in my comments, I'll be explicit about my suggestion: a) submit outcome in a way that looks like the rest of boost libraries so it would be evaluated by the same criteria that other boost libraries are. b) Make you're own Nial-Boost-Lite repo which applies you're pre-processing stuff to all the boost library you want to include. It could, if convenient, include any or all of boost libraries as subprojects. I would expect that you could find a way to generate this automatically from any C++ header source. See how that flies. And there is precedent for this. I doubt anyone would be surprisd at this point that I created the Boost Library Incubator as my prototype of Boost 2.0 I can't say it's been successful in achieving this goal, though it has some useful value. Robert Ramey
I dispute all of the above assertions. There is not evidence for them - how could there be as they are not true? And even if they were true, they would in no way be an argument for the library, up ending boost via the inclusion of a single very small and simple library or anything else.
I find it astonishing how threatened some people are by a highly non-intrusive internal implementation library which has no effect on: 1. The end user experience. 2. Any other Boost library. 3. Boost itself. People are making mountains out of molehills. Nobody has given a single technical reason why the presence of that internal implementation library is a technical showstopper to anything except the maintainer's maintenance burden, which is my problem, not yours. I'll accept Bjorn's feedback that its unspecified nature makes it harder to review implementation as part of review, but I genuinely thought people would just run g++ -MM and get on with it.
Although it's implicit in my comments, I'll be explicit about my suggestion:
a) submit outcome in a way that looks like the rest of boost libraries so it would be evaluated by the same criteria that other boost libraries are.
As Jon Kalb mentioned during CppChat only yesterday, there has been a wholesale move away from libraries entering monolithic collections like Boost in favour of people's own github repos where few end users find them. And that has been a negative thing with regard to WG21 standardisation. As I hinted at strongly in my technical description of boost-lite, what's coming next is that libraries will join **multiple** collections of standards aspiring C++ libraries. There are already mini-Boost's popping up, most of them are individual github collections, but it won't be long now - thanks to git and git submodules - that a C++ library will become part of many collections simultaneously. All my libraries have been written to be good neighbours to any other C++, and to be highly flexible for end use cases. It's a huge value add for the burgeoning ecosystem of next generation C++ libraries. People don't want intrusive C++ libraries which **impose** foreign build systems and command line tooling and configuration on end users any more. They want libraries you can drop into your C++ as a git submodule or a single file include and no faffing around needed. That's the future. If Boost is unwilling to accept such good neighbour libraries as Outcome is, then I feel very sorry about that. I have tried very hard to make using Outcome a superb end user experience, and for some reason the techniques I have employed scare some people here. A shame. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Although it's implicit in my comments, I'll be explicit about my suggestion:
a) submit outcome in a way that looks like the rest of boost libraries so it would be evaluated by the same criteria that other boost libraries are.
As Jon Kalb mentioned during CppChat only yesterday, there has been a wholesale move away from libraries entering monolithic collections like Boost in favour of people's own github repos where few end users find them. And that has been a negative thing with regard to WG21 standardisation.
As I hinted at strongly in my technical description of boost-lite, what's coming next is that libraries will join **multiple** collections of standards aspiring C++ libraries. There are already mini-Boost's popping up, most of them are individual github collections, but it won't be long now - thanks to git and git submodules - that a C++ library will become part of many collections simultaneously. All my libraries have been written to be good neighbours to any other C++, and to be highly flexible for end use cases. It's a huge value add for the burgeoning ecosystem of next generation C++ libraries.
It's just funny to see how you advertise your library to be a good citizen to be used by many others but at the same time you claim that Boost itself is a bad citizen as parts of it are used by other libraries... But I got it: you're the only person on this world who really understands what C++ developers want and how irrational everybody is who is not seeing things your way. As I said already: good luck, and I may add good riddance. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
For any library, I tend to lean towards more-complicated internals if
it means a less complicated external usage/API. And I think you are
saying the same thing. Great.
However, I think I am hearing concerns that the internals (and not
just code but the process behind it) may be so complicated, that there
are fears for those (besides you) that may need to dive into those
internals. Either because they find some strange bug (maybe in an
unsupported compiler, etc) or in case you some day can no longer be
the maintainer, or whatever.
Or they just want to dive in to learn the code, which programmers often do.
More succinctly,
How hard would it be for me to become the maintainer of outcome?
How many non-outcome things would I need to understand? Should it be
that hard? Shouldn't outcome be easy? And how important should this be
in a review?
I would appreciate answers to that from not just Niall, but anyone
else who understands the inner workings (as it is always hard for the
author to see their work from someone else's perspective).
P.S. the internals of many (most?) boost libraries are hard to
understand - too many macros, etc. Is Outcome on the same level,
better? worse? Even if it is on the same level of most of boost, I'm
sad :-(
Tony
On Sun, May 28, 2017 at 2:43 PM, Niall Douglas via Boost
I dispute all of the above assertions. There is not evidence for them - how could there be as they are not true? And even if they were true, they would in no way be an argument for the library, up ending boost via the inclusion of a single very small and simple library or anything else.
I find it astonishing how threatened some people are by a highly non-intrusive internal implementation library which has no effect on:
1. The end user experience.
2. Any other Boost library.
3. Boost itself.
People are making mountains out of molehills. Nobody has given a single technical reason why the presence of that internal implementation library is a technical showstopper to anything except the maintainer's maintenance burden, which is my problem, not yours.
I'll accept Bjorn's feedback that its unspecified nature makes it harder to review implementation as part of review, but I genuinely thought people would just run g++ -MM and get on with it.
Although it's implicit in my comments, I'll be explicit about my suggestion:
a) submit outcome in a way that looks like the rest of boost libraries so it would be evaluated by the same criteria that other boost libraries are.
As Jon Kalb mentioned during CppChat only yesterday, there has been a wholesale move away from libraries entering monolithic collections like Boost in favour of people's own github repos where few end users find them. And that has been a negative thing with regard to WG21 standardisation.
As I hinted at strongly in my technical description of boost-lite, what's coming next is that libraries will join **multiple** collections of standards aspiring C++ libraries. There are already mini-Boost's popping up, most of them are individual github collections, but it won't be long now - thanks to git and git submodules - that a C++ library will become part of many collections simultaneously. All my libraries have been written to be good neighbours to any other C++, and to be highly flexible for end use cases. It's a huge value add for the burgeoning ecosystem of next generation C++ libraries.
People don't want intrusive C++ libraries which **impose** foreign build systems and command line tooling and configuration on end users any more. They want libraries you can drop into your C++ as a git submodule or a single file include and no faffing around needed. That's the future.
If Boost is unwilling to accept such good neighbour libraries as Outcome is, then I feel very sorry about that. I have tried very hard to make using Outcome a superb end user experience, and for some reason the techniques I have employed scare some people here. A shame.
Niall
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 6/3/17 2:59 PM, Gottlob Frege via Boost wrote:
How many non-outcome things would I need to understand? Should it be that hard? Shouldn't outcome be easy? And how important should this be in a review?
I would appreciate answers to that from not just Niall, but anyone else who understands the inner workings (as it is always hard for the author to see their work from someone else's perspective).
P.S. the internals of many (most?) boost libraries are hard to understand - too many macros, etc. Is Outcome on the same level, better? worse? Even if it is on the same level of most of boost, I'm sad :-(
I'm going to rephrase this question in a more general form. Is it important to understand the internal implementation of a library? If the answer is yes, how important is it? To me the central questions are: a) is this library intuitive to use correctly? b) is this library hard to use incorrectly? c) is it more work to figure out the above than it is to just write the functionality from scratch? That is, is usage of the library economic? d) can I verify that it actually does what I think it does? a, b, c are basically variations on the same idea. I need yes answers to all of these. Get to "yes" on these will involve reviewing documentation, and sometimes tests, examples and code which implements the library. In addition to these things, the library will need a clearly stated purpose describing what it is meant to do. "parse any json file so contents can be easily processed by a user's program" is such a statement. In other words can I understand what this thing does without having fill my head with a lot of detail. If I can't do this I can't use it. I know this sounds trivial - but it's not. It's amazing how many boost libraries don't pass this bar - and boost is way better than most. Assuming we're past a, b, and c - what about d)? Why do I need to care about what's under the covers. There are a couple of reasons. a) I want to be able to verify that it in fact works the way I think it does. I want to see what the code does. No, I'm not necessarily going to go through it line by line, but I expect to be able to trace down to the bottom for a few cases to know that it is in fact doable should I need to track down some problem. But more than that, if I can't do this even for a couple of cases, I don't have confidence that the implementation is reliable. Testing is helpful in convincing me there is quality there. But it's not the same as knowing I trace through some cases and verify that it does every required step and only those required steps. Only then can I feel confident in using the code in something important. I realize that this is a very, very high bar that most of us boost authors have difficulty meeting. It's just very hard. It takes a lot of work, stamina and brain power. More tools, tests, etc can't do all the work. It's just very hard. So, I'm inclined to stick to things that are simpler to understand. (usually). Something like shared_ptr I and understand. something like state_saver I can understand. I could probably understand outcome but I'm concerned that something which would seem so simple can require this amount of discussion. It's just not easy to be confident about it under these circumstances. Note that it's quite possible that were it presented in a different manner, I might have a totally different opinion. I'm not saying it's bad, I'm saying I can't understand it in the time I think it would take to write my own less general version. But I also have to mention things like spirit, serialization, boost.units. These are things that one can't hope to really understand the way one really should. This might be why places like Google exclude these types of components from their list of libraries approved for usage at Google. But I still use them. Doesn't this contradict what I said above? Hmmmm - yeah except the economic argument. These packages save so much future time, I'm willing to break the other rules to include them. There is no way I'm going write my own alternatives so it's either use them (and pray they actually work) or just not do what they do. Maybe the way to say this - to quote our spiritual guide - keep simple things simple. to which I would add - If you can. Robert Ramey
2017-06-04 0:39 GMT+02:00 Robert Ramey via Boost
On 6/3/17 2:59 PM, Gottlob Frege via Boost wrote:
How many non-outcome things would I need to understand? Should it be
that hard? Shouldn't outcome be easy? And how important should this be in a review?
I would appreciate answers to that from not just Niall, but anyone else who understands the inner workings (as it is always hard for the author to see their work from someone else's perspective).
P.S. the internals of many (most?) boost libraries are hard to
understand - too many macros, etc. Is Outcome on the same level, better? worse? Even if it is on the same level of most of boost, I'm sad :-(
I'm going to rephrase this question in a more general form.
Is it important to understand the internal implementation of a library? If the answer is yes, how important is it?
To me the central questions are:
a) is this library intuitive to use correctly? b) is this library hard to use incorrectly? c) is it more work to figure out the above than it is to just write the functionality from scratch? That is, is usage of the library economic?
d) can I verify that it actually does what I think it does?
a, b, c are basically variations on the same idea. I need yes answers to all of these. Get to "yes" on these will involve reviewing documentation, and sometimes tests, examples and code which implements the library. In addition to these things, the library will need a clearly stated purpose describing what it is meant to do. "parse any json file so contents can be easily processed by a user's program" is such a statement. In other words can I understand what this thing does without having fill my head with a lot of detail. If I can't do this I can't use it. I know this sounds trivial - but it's not. It's amazing how many boost libraries don't pass this bar - and boost is way better than most.
Assuming we're past a, b, and c - what about d)? Why do I need to care about what's under the covers. There are a couple of reasons.
a) I want to be able to verify that it in fact works the way I think it does. I want to see what the code does. No, I'm not necessarily going to go through it line by line, but I expect to be able to trace down to the bottom for a few cases to know that it is in fact doable should I need to track down some problem. But more than that, if I can't do this even for a couple of cases, I don't have confidence that the implementation is reliable. Testing is helpful in convincing me there is quality there. But it's not the same as knowing I trace through some cases and verify that it does every required step and only those required steps. Only then can I feel confident in using the code in something important.
I realize that this is a very, very high bar that most of us boost authors have difficulty meeting. It's just very hard. It takes a lot of work, stamina and brain power. More tools, tests, etc can't do all the work. It's just very hard.
So, I'm inclined to stick to things that are simpler to understand. (usually). Something like shared_ptr I and understand. something like state_saver I can understand. I could probably understand outcome but I'm concerned that something which would seem so simple can require this amount of discussion. It's just not easy to be confident about it under these circumstances. Note that it's quite possible that were it presented in a different manner, I might have a totally different opinion. I'm not saying it's bad, I'm saying I can't understand it in the time I think it would take to write my own less general version.
But I also have to mention things like spirit, serialization, boost.units. These are things that one can't hope to really understand the way one really should. This might be why places like Google exclude these types of components from their list of libraries approved for usage at Google. But I still use them. Doesn't this contradict what I said above? Hmmmm - yeah except the economic argument. These packages save so much future time, I'm willing to break the other rules to include them. There is no way I'm going write my own alternatives so it's either use them (and pray they actually work) or just not do what they do.
Maybe the way to say this - to quote our spiritual guide - keep simple things simple. to which I would add - If you can.
Robert, I agree with what you say about a library implementation. I also agree that in case of Outcome review the shape of the documentation was the reason for misunderstandings that could have been otherwise avoided. But to make the picture complete, I would add this is one of these "vocabulary type" libraries, and that this alone causes lots of controversies. I remember the same form standardizing `boost::optional`. People have very strong expectations which are often contradictory. One says, Optional MUST provide `operator->`and explicit conversion to bool, otherwise the interface is counter-intuitive and does not fit into C++. Others say, it MUST NOT provide these clever operators, as this is the source of all bus. Or, "only pointer are allowed to have operator* and operator->. One says, implicit conversion from T is unsafe and is the root cause of many problems and gotchas with optional; the other says, "if I cannot write `return 1`, optional is useless". Why don't we have implicit conversion to T as other languages? Some people demand that Optional must provide iterators, as otherwise it cannot be used in generic contexts. Nearly every decision is controversial. The discussion about having or not having narrow interfaces: it isn't related especially to Outcome. It applies to practically any "vocabulary type". It is this being a fundamental "vocabulary type" that somehow attracts discussions. Regards, &rzej;
On 28/05/2017 04:08, Peter Dimov wrote:
The objection is that the non-preprocessed form, which is more convenient when one needs to look at the implementation, study how it's organized, fix a problem one's having (on mignw64, for instance), then prepare a pull request, does not compile unless one has a foreign submodule installed, which in turn picks up two more, even more foreign, submodules.
It's not possible to have foreign submodules in a Boost distribution, so the choice there would be to either not provide the non-preprocessed form at all, or provide it in a non-functional form.
Presumably the Boost archive distribution form would have the source code from the submodules "baked in". They're just subdirectories that contain files, after all. (ie. the Boost archive generator just needs to do that submodule update, then it can forget that they were submodules to start with. It might already be doing this, since the top-level uses submodules.) Only the users of the git repo need to care that submodules exist (and they should know how to deal with them, as this is standard git); users of the zip just get files and they don't care where they came from. Though the downside of this is that it will inevitably duplicate the code in the pre-processed header, and perhaps confuse users about which one to include or which one needs to be corrected in case of problems. Though in the latter case if someone submits a pull request against the pre-processed version it will be up to Niall to locate and correct the corresponding non-pre-processed version accordingly; that's just a natural consequence of choosing to distribute the source in that form.
Yes, and I already answered it, with your swiftly proceeding to ignore my answer. Probably because you didn't understand it, which of course means it's irrational.
To repeat, it's not possible for a Boost user to not want a dependency on Boost. A Boost user already has Boost. This is tautological.
Yes and no. While this is true on the surface there is a deeper meaning to it when you probe. What you'll probably find is that the "Boost user who doesn't want Boost" actually just wants to avoid certain sub-libraries, eg. using C++11 types instead of Boost types, or avoiding MPL, etc. I don't think anyone objects to depending on the core (Config, Core, and Exception, mostly). Or if they do, they need their head examined.
I have also received quite a bit of private email begging me to keep Outcome free of a hard Boost dependency if accepted. I have asked them to say this publicly here, but I would assume they cannot for some reason or other. Quite a few talked about how their multinational's processes would find a standalone Boost.Outcome much much easier to deal with than one with dependency on other Boost libraries. Some of those are household name multinationals, and what they report matches my experience at BlackBerry.
This probably deserves a separate thread. My understanding is that we have three expectations:
1. Boost developers do not want duplication in Boost.
Some Boost developers are ideologically and irrationally attached to "how things are done around here", yes.
I don't know about not wanting duplication in Boost. There is a ton of duplication in Boost. It's been waved through in peer review many times in the past.
This is not true. It was always the idea of Boost to create as little code duplication as possible. Why do you think we have so many cross dependencies between Boost libraries? And yes, it has happened, but it should never have been intentionally waved through.
2. Non-boost users of Outcome do not want a dependncy on Boost.
Actually there is overwhelming evidence that Boost **users** do not want a dependency on Boost. But I've been saying that for years now.
This is just BS, sorry. Boost users choose Boost because they realize that reproducing Boost functionalities would cost them even more than to live with the disadvantages of Boost, namely having to deal with dozens of (partly incompatible) versions, an isolated and arcane build system, insufficient protection from ABI differences between library nmodules which share the same name, ... you name it.
Whilst Outcome is in an unstable state, the actual namespace used is:
namespace boost { namespace outcome { inline namespace v1_GITSHA { ... } } }
This sounds like we are doing a formal review of a library in an unstable state.
Ok, unstable ABI then. Right now I am not promising the ABI won't change. When I do promise that the ABI is written permanently into stone, you'll get your boost::outcome::v1 namespace, and per commit it'll be checked for breaking changes by the abi-compliance-checker.
Again, only half-way true. The _design_ of the whole library is changing under our noses (not just parts of the implementation) while we're supposed to make an educated decision whether this library is ready for Boost or not. Once upon a time a Boost review was supposed to refer to a single fixed source code version and not a moving target as it is for this library. The decision whether somebody would like to see a library accepted into Boost or not should not be based on wishful thinking (that the author will implement things eventually) or on unsubstantiated promises. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
Again, only half-way true. The _design_ of the whole library is changing under our noses (not just parts of the implementation) while we're supposed to make an educated decision whether this library is ready for Boost or not.
What has actually changed in the presented library? 1. outcome<T>/result<T> has been renamed to checked_optional_outcome<T>/checked_optional_result<T>. 2. A few extraneous member functions and types have been removed. 3. A few bug fixes not affecting the public API. Other than those, nothing has changed from the presented library. I agree all this discussion and noise makes it seem more has happened, but most of that discussion is speculative. I have only agreed to the above changes only.
Once upon a time a Boost review was supposed to refer to a single fixed source code version and not a moving target as it is for this library. The decision whether somebody would like to see a library accepted into Boost or not should not be based on wishful thinking (that the author will implement things eventually) or on unsubstantiated promises.
Most of the wishful thinking has come from reviewers wanting to redesign the library according to their preferences. There is no moving target here. What has been presented for review is what will be accepted into Boost if acceptance is recommended. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Again, only half-way true. The _design_ of the whole library is changing under our noses (not just parts of the implementation) while we're supposed to make an educated decision whether this library is ready for Boost or not.
What has actually changed in the presented library?
1. outcome<T>/result<T> has been renamed to checked_optional_outcome<T>/checked_optional_result<T>.
2. A few extraneous member functions and types have been removed.
3. A few bug fixes not affecting the public API.
Other than those, nothing has changed from the presented library. I agree all this discussion and noise makes it seem more has happened, but most of that discussion is speculative. I have only agreed to the above changes only.
I believe the following email is outlining the plan on how the library has to be changed based on review feedback: http://tinyurl.com/y9n2xpjh. It was written by you, Niall, wasn't it?
Once upon a time a Boost review was supposed to refer to a single fixed source code version and not a moving target as it is for this library. The decision whether somebody would like to see a library accepted into Boost or not should not be based on wishful thinking (that the author will implement things eventually) or on unsubstantiated promises.
Most of the wishful thinking has come from reviewers wanting to redesign the library according to their preferences.
There is no moving target here. What has been presented for review is what will be accepted into Boost if acceptance is recommended.
You plan for the library to be changed massively in the near future (in API, design, and implementation). So even _you_ are not happy with it. So why accept or reject now if we don't know what the outcome (pun intended) will be? I'd like to repeat my suggestion for the review manager to consider rescheduling this review without an acceptance decision now. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
I'd like to repeat my suggestion for the review manager to consider rescheduling this review without an acceptance decision now.
Usual fear, uncertainty and doubt from this individual. He is a consistently negative person - anything I ever propose he always agitates the same way, and I hope people will ignore his trolling. I will restate that apart from removal of a few member functions and types, and renaming outcome<T> and result<T>, the presented library is not going to change much because I have not been persuaded of any defects in it. I have been persuaded to add non-empty-capable varieties, and narrow observer varieties. But they're all typedefs of the same implementation, just as is currently the case in the presented library where there is a single implementation typedefed into varieties. The only major change in implementation I've agreed to is replacement of preprocessor-based stamping out of varieties with a template-based implementation which does exactly the same thing. Such limited changes are hardly cause to reschedule a review, but I'll leave that to the review manager to decide. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
I'd like to repeat my suggestion for the review manager to consider rescheduling this review without an acceptance decision now.
Usual fear, uncertainty and doubt from this individual. He is a consistently negative person - anything I ever propose he always agitates the same way, and I hope people will ignore his trolling.
Let me simply cite what you wrote in response to Robert's email earlier on this email thread (https://tinyurl.com/y7ereujg): <quote> Well, an ad hominem attack had to happen at some point. </quote> Good luck! Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
On 05/27/2017 04:40 PM, Niall Douglas via Boost wrote:
I still hold open the offer of a fully Boost flavoured edition of Outcome. I think it a mistake personally, but the offer is there. I've given up on trying to instil awareness of the end user experience of Boost into people on boost-dev.
I think your solution to dual boost/standalone version is all backwards. An alternative is to have the Boost.Outcome as the main repository. This uses Boost.Config and possibly other accepted Boost libraries, and hides implementation details in boost::outcome::detail. No dependency on "boost-lite". The standalone repository includes Boost.Outcome as a submodule. It also contains your substitutes for Boost.Config etc. (i.e. "boost-lite"), as well as CMake scripts.
I still hold open the offer of a fully Boost flavoured edition of Outcome. I think it a mistake personally, but the offer is there. I've given up on trying to instil awareness of the end user experience of Boost into people on boost-dev.
I think your solution to dual boost/standalone version is all backwards.
An alternative is to have the Boost.Outcome as the main repository. This uses Boost.Config and possibly other accepted Boost libraries, and hides implementation details in boost::outcome::detail. No dependency on "boost-lite".
The standalone repository includes Boost.Outcome as a submodule. It also contains your substitutes for Boost.Config etc. (i.e. "boost-lite"), as well as CMake scripts.
I can see why you might think that organisation superior, and I did start out with that design. In fact, boost-lite used to define the exact same macros as Boost, precisely because of that organisation, the idea was that boost-lite was a substitute for Boost. But I inverted it after a bit of trial, so now boost-lite is an internal implementation detail. The problem is that putting the common stuff on the outside with a git submodule SHA stamp for the libraries makes your developer workflow quite painful as everything must be kept in lockstep. All my libraries are specifically designed to work alongside different versions of themselves, so there is absolutely no problem if say AFIO v2 uses one version of Outcome, whilst another library uses a different version of Outcome. And that lets you avoid having to keep everything up to date all the time. Indeed, for a long while there, AFIO would not compile with latest Outcome for something approaching six months, but it didn't matter because AFIO was SHA pinned to an Outcome and boost-lite which *did* work. Does this make sense? BTW, the name boost-lite is not long for this world as it has changed its purpose and role. I am still thinking of a new name more suitable for what it now is: a set of highly reusable utilities common between all my libraries. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 05/27/2017 06:43 PM, Niall Douglas via Boost wrote:
I can see why you might think that organisation superior, and I did start out with that design. In fact, boost-lite used to define the exact same macros as Boost, precisely because of that organisation, the idea was that boost-lite was a substitute for Boost.
The standalone Outcome does not have to use its own namespace. It could retain the boost::outcome namespace. That way we can remove yet another dependency (the part of "boost-lite" previously known as APIBind.) That gives us a clean separation where the Boost.Outcome repository is "untainted" by any foreign submodules, and the standalone Outcome repository is a Boost.Outcome without a Boost dependency. How your Boost emulation layer is included in the standalone Outcome repository is out of scope for this review, but CMake offers sufficient choices (sub-directories, pkg-config, downloadable external projects, etc.)
I can see why you might think that organisation superior, and I did start out with that design. In fact, boost-lite used to define the exact same macros as Boost, precisely because of that organisation, the idea was that boost-lite was a substitute for Boost.
The standalone Outcome does not have to use its own namespace. It could retain the boost::outcome namespace. That way we can remove yet another dependency (the part of "boost-lite" previously known as APIBind.)
If Outcome is accepted in std-flavoured form, I already intend to delete the namespace bindings code entirely. They have only hung around due to this upcoming review.
That gives us a clean separation where the Boost.Outcome repository is "untainted" by any foreign submodules, and the standalone Outcome repository is a Boost.Outcome without a Boost dependency.
There is no "taint" from the boost-lite submodule. It can be included into any translation unit without ill effect. It is a good neighbour to all other C++, including different versions of itself. You may find a reply to Robert sent recently with a description of one post-approval Boost integration strategy I might take (use boost-lite submodule if checked out, else fall back onto hard Boost dependency). But I consider all that process and packaging trivia. None of it is hard. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 05/28/2017 02:10 PM, Niall Douglas via Boost wrote:
If Outcome is accepted in std-flavoured form, I already intend to delete the namespace bindings code entirely. They have only hung around due to this upcoming review.
In that case, what is left of "boost-lite"?
Furthermore, can you describe what you mean by "std-flavoured form"?
Does it mean that Outcome is hardwired to
There is no "taint" from the boost-lite submodule. It can be included into any translation unit without ill effect. It is a good neighbour to all other C++, including different versions of itself.
"boost-lite" is not reviewed by Boost, and therefore not suitable for use in a Boost library, whether as submodule or something else. That is why I am suggesting an alternative.
You may find a reply to Robert sent recently with a description of one post-approval Boost integration strategy I might take (use boost-lite submodule if checked out, else fall back onto hard Boost dependency).
You may not get approval until this is resolved.
Bjorn Reese wrote:
Does it mean that Outcome is hardwired to
, without support for Boost.System?
With my recent patch to Boost.System, it's possible to store boost::system::error_code into std::error_code, so Outcome that stores std::error_code can still support boost::system::error_code.
If Outcome is accepted in std-flavoured form, I already intend to delete the namespace bindings code entirely. They have only hung around due to this upcoming review.
In that case, what is left of "boost-lite"?
The namespace bindings make up a small part of boost-lite, and as I mentioned, I have been intending to delete them pending this review. There are a wide range of generic algorithms and utilities built on top of the C++ 14 STL, just like how Boost originally started life. A reasonable cross selection of these generic algorithms are used by Outcome and its unit test suite.
Furthermore, can you describe what you mean by "std-flavoured form"? Does it mean that Outcome is hardwired to
, without support for Boost.System? Are there more differences?
std-flavoured form is the form presented for review. It uses no Boost code. If std-flavoured form is accepted, I would permanently retire any possibility of a boost-flavoured form by deleting the support code in boost-lite.
There is no "taint" from the boost-lite submodule. It can be included into any translation unit without ill effect. It is a good neighbour to all other C++, including different versions of itself.
"boost-lite" is not reviewed by Boost, and therefore not suitable for use in a Boost library, whether as submodule or something else. That is why I am suggesting an alternative.
Proposed Boost libraries with internal standalone libraries have been reviewed and accepted into Boost in the past. I respectfully suggest that people are turning a molehill into a mountain just because git submodules hurt their heads somehow. This stuff is not important, it's just dots on i's and crosses on t's stuff. Plumbing.
You may find a reply to Robert sent recently with a description of one post-approval Boost integration strategy I might take (use boost-lite submodule if checked out, else fall back onto hard Boost dependency).
You may not get approval until this is resolved.
I see no point in making concrete statements about how I would lay piping and plumbing. Lots depends on things I don't know answers to yet because the relevant people haven't given me decisions yet, and they won't make those decisions until they know if Outcome is entering Boost or not. For example, if the relevant people don't want Outcome's unit tests to run as part of Boost release testing, then I could give you a very easy answer on plumbing right now. But if they wanted all of the unit testing to run, they would need to accept nearly all of the contents of boost-lite as necessary because Boost.Test won't work with C++ exceptions disabled, and boost-lite's unit test suite uses most of boost-lite's code. So whilst Outcome could be adapted to not use boost-lite, its complete test suite cannot. And that is but one of many decisions to be made by others which is out my control. If the lack of detail on unimportant implementation plumbing is what causes a rejection, then I would find that very unfortunate and short sighted, especially as plumbing does not affect the end user experience. That detail concerns the maintainers, and mostly me, only. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 05/28/2017 03:41 PM, Niall Douglas via Boost wrote:
There are a wide range of generic algorithms and utilities built on top of the C++ 14 STL, just like how Boost originally started life. A reasonable cross selection of these generic algorithms are used by Outcome and its unit test suite.
Can you be more specific? What parts of "boost-lite" does Outcome need?
Proposed Boost libraries with internal standalone libraries have been reviewed and accepted into Boost in the past. I respectfully suggest
Which internal standalone libraries? Where any of those not reviewed?
I see no point in making concrete statements about how I would lay piping and plumbing. Lots depends on things I don't know answers to yet because the relevant people haven't given me decisions yet, and they won't make those decisions until they know if Outcome is entering Boost or not.
Plumbing is not the issue. The inclusion of an un-reviewed library is.
There are a wide range of generic algorithms and utilities built on top of the C++ 14 STL, just like how Boost originally started life. A reasonable cross selection of these generic algorithms are used by Outcome and its unit test suite.
Can you be more specific? What parts of "boost-lite" does Outcome need?
I figured this so easy to calculate I didn't bother listing this, but here you go: ned@lyta:~/windocs/boostish/outcome/test$ g++-6 -MM -Wall -Wextra -std=c++1y -pthread -O3 -DNDEBUG unittests.cpp -lrt -I../include/boost/outcome/v1.0 -I.. -DBOOST_OUTCOME_DISABLE_PREPROCESSED_INTERFACE_FILE unittests.o: unittests.cpp ../include/boost/outcome/outcome.hpp \ ../include/boost/outcome/version.hpp \ ../include/boost/outcome/v1.0/monad.hpp \ ../include/boost/outcome/v1.0/config.hpp \ ../../boost-lite/include/config.hpp \ ../../boost-lite/include/revision.hpp \ ../../boost-lite/include/cpp_feature.h ../../boost-lite/include/import.h \ ../../boost-lite/include/detail/preprocessor_macro_overload.h \ ../include/boost/outcome/v1.0/../revision.hpp \ ../../boost-lite/include/bind/stl11/std/system_error \ ../include/boost/outcome/v1.0/bad_outcome.hpp \ ../include/boost/outcome/v1.0/error_code_extended.hpp \ ../../boost-lite/include/ringbuffer_log.hpp \ ../../boost-lite/include/config.hpp \ ../include/boost/outcome/v1.0/value_storage.hpp \ ../include/boost/outcome/v1.0/detail/value_storage.ipp \ ../../boost-lite/include/tribool.hpp \ ../include/boost/outcome/v1.0/detail/basic_monad.ipp \ ../include/boost/outcome/v1.0/detail/monad_policy.ipp \ ../include/boost/outcome/v1.0/detail/expected_policy.ipp \ ../../boost-lite/include/boost/test/unit_test.hpp \ ../../boost-lite/include/boost/test/../../config.hpp \ ../../boost-lite/include/boost/test/../../console_colours.hpp \ ../../boost-lite/include/boost/test/../../config.hpp \ ../../boost-lite/include/allocator_testing.hpp So, breaking that out: - End user #include of Outcome: - Easily replaceable with Boost.Config and Boost.Preprocessor: ../../boost-lite/include/config.hpp ../../boost-lite/include/revision.hpp ../../boost-lite/include/cpp_feature.h ../../boost-lite/include/import.h ../../boost-lite/include/detail/preprocessor_macro_overload.h - Hard to replace with Boost, would need local copy: ../../boost-lite/include/ringbuffer_log.hpp So this isn't too bad to fall back onto Boost if a boost-lite subrepo is not checked out. - Regression testing Outcome (exceptions enabled): - Easily replaceable with Boost.Test: ../../boost-lite/include/boost/test/unit_test.hpp ../../boost-lite/include/boost/test/../../console_colours.hpp - Hard to replace with Boost, would need local copy: ../../boost-lite/include/allocator_testing.hpp - Regression testing Outcome (exceptions disabled): - Not possible to replace with Boost The exceptions enabled testing is easy to fall back onto Boost with, I intentionally used the exact same macros as Boost.Test does. The exceptions disabled testing I don't think it is possible with Boost, you need boost-lite for that.
Proposed Boost libraries with internal standalone libraries have been reviewed and accepted into Boost in the past. I respectfully suggest
Which internal standalone libraries? Where any of those not reviewed?
Back when I asked about that here I was told that the internal libraries were reviewed as part of the implementation, but not as part of any public API.
I see no point in making concrete statements about how I would lay piping and plumbing. Lots depends on things I don't know answers to yet because the relevant people haven't given me decisions yet, and they won't make those decisions until they know if Outcome is entering Boost or not.
Plumbing is not the issue. The inclusion of an un-reviewed library is.
I must admit to great surprise at how hard people are finding this. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
participants (10)
-
Andrzej Krzemienski
-
Bjorn Reese
-
Deniz Bahadir
-
Gavin Lambert
-
Glen Fernandes
-
Gottlob Frege
-
Hartmut Kaiser
-
Niall Douglas
-
Peter Dimov
-
Robert Ramey