== The problem.
TL;DR: we are having huge troubles with usability and popularity!
Quite a lot of companies forbid using Boost because:
* it provides vocabulary types, that should be the same across the
whole project (like shared_ptr, filesystem::path or optional).
Otherwise it's hard to combine different APIs
* it is huge, in consists of legacy on more than a half, with a lot of
dependencies between libraries. This is extremely painful for big
companies, because there's no efficient distributed build system. Each
company invents it's own and/or tries to minimize headers by all
means.
New companies (startups) also avoid Boost:
* "We are using C++17, we do not want legacy libraries with C++98 support"
* Junior developers are confused by multiple vocabulary types. "Should
we use boost::optional or std::optional?"
* hard to upgrade, because symbols are not versioned
ISO C++ WG21 community not willing to push prototypes into Boost. "We
aim to establish "existing practice" and provide reference
implementations so that Boost libraries are suitable for eventual
standardization." - that's not really true any more.
== The Solution
TL;DR: we need a C++17 fork of Boost with close to 0 dependencies
between libraries and namespace versioning.
С++17 provides many vocabulary types, feature test macro and a bunch
of features for variadic templates. All of that allows us to drop a
lot of weight and fix majority of popularity and usability problems.
Rule of a thumb should be: "If the C++17 provides that functionality -
use the standard version".
That approach would allow to loose a lot of weight, do not mess with
vocabulary types and significantly reduce dependencies
https://pdimov.github.io/boostdep-report/master/module-levels.html
By levels:
config 0 -> we probably would not need it any more
assert 1 -> 0
core 2 -> 1 (or 0 if we merge it with asser)
smart_ptr 4 -> 2
exception 5 -> 2
stacktrace 5 -> 2
intrusive 5 -> 2
outcome 6 -> 3
container 6 -> 3
gil 11 -> 2?
context 16 -> 2?
dll 17 -> 1
asio 18 -> 3?
beast 19 -> 4?
== The Path
TL;DR: we should start the Boost17 now and ship it as we are ready.
Old Boost should be still available.
The new approach requires quite a lot of effort and not all the
maintainers have enough time to do the migration. We should keep
releasing the existing Boost, while migrating the libraries to the
Boost17.
The migration is not as hard as it seems. It took 2 or 3 days to make
Boost.DLL work with either boost or std filesystem. It could be done
in less than a day, if I do not have to support the Boost filesystem.
== Action points
0) Discuss
1) Bury the idea, wait for a few years, goto 0); or make a boost17
repo with the same layout as the existing one, but without submodules
2) start the migration
--
Best regards,
Antony Polukhin
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Not really. Serialization library can not be replaced with C++17
Standard library, so we can move it to Boost17. This would require
some effort in dropping MPL dependency or replacing it with Mp11,
untying it from boost::variant and others
> Boost Histogram has level 2 dependencies without Boost Serialization, which is opt-in. With Boost Serialization is has level 18, because Boost Serialization depends on the world. AFAIK rewriting Boost Serialization to drop Boost MPL would be a major effort.
I'm doubting that. A quick search shows that Serialization mostly uses
MPL things that are available in C++17 (like enable_if, true_type and
static_assert). Effort is required, but it is bearable.
Because of that effort we need time to make Boost17 usable. I'd be
able to move stacktrace and dll libraries in a few weeks. Mp11, Pfr
and Predef are ready to move. It may take much more time to move
Histogram or GIL
> Besides that, demanding 0 dependencies has serious drawbacks. Boost Histogram uses Boost functionality where there is no equivalent in the stdlib, not even in C++17 (Boost config, Boost throw_exception, Boost mp11, Boost core). I already reimplemented functionality in Boost Histogram that was originally found in other Boost libs to reduce coupling, like Boost Iterator and Boost Multiprecision. Boost Beast does this, too, it has its own variant type and more.
Not 0, close to 0. It is fine to reuse libraries if there is no
Standard Library replacement. It is not fine to use Boost version, if
there is a close alternative in the C++17
> A non-fundamental library like Histogram or Beast has the choice to either suffer a significant loss of functionality or use its own private implementation of Boost functionality to give the appearance of low dependencies. This inflates the private code of these libraries and maintaining private (duplicated) implementations is frankly crazy. We bundle Boost to make use of **synergies** between the libs. I should not use my private (potentially buggy) implementation of Boost iterator, I should use the official maintained (and hopefully less buggy) one.
Yep, we need to keep being reasonable during migration.
> Best regards,
> Hans
--
Best regards,
Antony Polukhin
_______________________________________________
We went over this multiple times. I'll just reiterate that I disagree
with this approach. Many Boost libraries are superior to std
equivalents, and I want to keep using them inside and outside Boost.
Also, I don't see why Boost libraries are not allowed to exist as an
extension over the std equivalents.
> That approach would allow to loose a lot of weight, do not mess with
> vocabulary types and significantly reduce dependencies
> https://pdimov.github.io/boostdep-report/master/module-levels.html
>
> By levels:
> config 0 -> we probably would not need it any more
That's wishful thinking, unfortunately. Compiler bugs still exist, and
C++17 support level is not uniform across compilers. Moving forward,
later C++ versions are also not uniformly implemented.
> assert 1 -> 0
I'm not aware of a standard replacement of Boost.Assert. <cassert> is
not one.
That's why we are not dropping the existing Boost. There are many
users who share your point of view. But there are others, and we have
more and more of them year over year.
> > That approach would allow to loose a lot of weight, do not mess with
> > vocabulary types and significantly reduce dependencies
> > https://pdimov.github.io/boostdep-report/master/module-levels.html
> >
> > By levels:
> > config 0 -> we probably would not need it any more
>
> That's wishful thinking, unfortunately. Compiler bugs still exist, and
> C++17 support level is not uniform across compilers. Moving forward,
> later C++ versions are also not uniformly implemented.
We have feature test macro and Predef. IMO that's enough.
> > assert 1 -> 0
>
> I'm not aware of a standard replacement of Boost.Assert. <cassert> is
> not one.
Assert drops dependency on Config and moves to Level 0. I'm not
proposing to purge the library.
--
Best regards,
Antony Polukhin
_______________________________________________
OK, how about a goal "Use the C++17 standard version whenever
possible"? With that goal we would reach the required result, but the
goal wording is less obscure.
--
Best regards,
Antony Polukhin
_______________________________________________
..well.. it might end up being true for different libraries than it
was before. More below.
> == The Solution
> TL;DR: we need a C++17 fork of Boost with close to 0 dependencies
> between libraries and namespace versioning.
>
> С++17 provides many vocabulary types, feature test macro and a bunch
> of features for variadic templates. All of that allows us to drop a
> lot of weight and fix majority of popularity and usability problems.
Well, yeah. There was a long period of time during which boost was a
very significant library,
because it had multithreading and better smart pointer. Then WG21 woke
up, shipped C++11,
and *bam*, a sizeable portion of boost's attraction vanished,
especially since C++11 was rapidly
adopted all over the place.
Boost still has things that are alluring. Networking is alluring for
quite some time still. Beast is alluring.
JSON is alluring. I find it interesting that the alluring bits are now
much more high-level than they
used to be. Perhaps there's something there.
Speaking for me in particular: What does annoy me, is if a boost library
uses the boost equivalent of a standard library vocabulary type in its
interface. E.g. boost::string_view instead of std::string_view or
boost::chrono::duration instead of std::chrono::duration.
As far as other duplications go:
If (and I really want to stress the if) using the boost version adds
significant compiletime or binary size overhead compared to the std version
then I'd also prefer if the std versions were used in the implementation
where possible. Otherwise I as a user don't really care.
The difference in compiletime might happen when the boost version using some
complex TMP (especially mpl) hacks whereas the std version can use more
efficient language constructs - and of course the std version almost always
ends up in my translation unit anyway, so compiling the boost equivalent is
just some additional work, but I don't have any experimental data to show if
there are actually any significant gains possible inpractice.
Regarding the proposal in general: Let me play the devil's advocate and ask, how
many active boost maintainers there are left. Are there enough to pull through with
something like that, without loosing a big chunk of the libs for which there
isn't a good c++17 equivalent yet (or ever).
Actually, that would be an argument for removing internal dependencies on boost
libs that have a c++17 equivalent: Reduced overall maintenence overhead for boost
once you are there and more flexibility for individual libs. But of course I'm
certainly not able to predict, if it would be a net win or not.
Best
Mike
> пт, 27 нояб. 2020 г. в 14:09, Francesco Guerrieri via Boost
> <bo...@lists.boost.org>:
> >
> > It's almost impossible to not top post from the phone, sorry!
> >
> > I am just a simple user, even if long dated. For what is worth I don't
> > agree with the goal of 0 dependencies between boost libraries: this for
> me
> > goes against the spirit of the language. I agree that dependencies can
> grow
> > out of control and the unnecessary proliferation should be avoided (a lot
> > of work has been done on that)...
>
> OK, how about a goal "Use the C++17 standard version whenever
> possible"? With that goal we would reach the required result, but the
> goal wording is less obscure.
>
> --
> Best regards,
> Antony Polukhin
>
Hi Antony,
this is a much clearer goal and I can see why a new library - or a subset
of the libraries - could aim for that. On the other hand Boost has a very
strong tradition and has proven its importance over and over, in providing
useful - or indispensable - tools even when the environment is old/obscure.
I don't think that it would be a good idea to suddenly "drop" this
support.. and why should developers, already a scarce resource, "waste
time" in removing support from something that is working and is potentially
useful for many users? On the other hand there could very well be cases of
libraries who are severely constrained if they are forced to support older
standards. In that case it would be a very reasonable call to "move" to
C++17.
But I wonder, is this really new? Hasn't every developer until now declared
a specific goal (I want to support only C++11 onward, even C++03... only
gcc X.Y for X and Y greater than ...)?
So are you calling to action for a more stringent requirement on C++17,
with a conversion of existing libraries and dropping (part of) the support
for older standards? or are you calling for a more enthusiastic adoption of
the new standard?
Sorry if I am missing something and thanks for your reply.
Best,
Francesco
ROFL.
"How would you link all the variations of that library if the library
were not a header-only library. You would have to have a different name
for each combination and the number of combinations would proliferate to
an unusable number. What a pipe dream you have !"
<g>
My point is that the biggest blocker for larger adoption of Boost.Test
is the size of monolithic Boost, not C++17 (which it supports).
Boost.Test depends on various libs among which preprocessor. It is good
design in a single library to reuse functions. But
* Boost.Test is not shipping some additional feature on top of
preprocessor, it is a client of it. Preprocessor is an implementation
detail of Boost.Test.
* Boost is not a single library (especially since "modular Boost"), it
is an umbrella of libraries. Each library is addressing a specific need
in the C++ world and has a specific target audience. Code reuse should
be thought as a way to bring features faster to market, this is a price
usually customer is ok to pay for. But then library coupling has various
downsides, such as slowing wider adoption and harming retention.
Preprocessor is a valuable library (especially now that I am trying to
re-implement a tiny subset of it) but that dependency has to be put in
the light of what it costs to customers, and the customers of boost.test
and preprocessor have little overlap.
Yes, that's exactly what I meant by "concrete type conversion".
Since the standard library string_view doesn't (currently?) do this, it
means that everybody will be writing their own string_views. (Or worse:
writing their own is_string_like.) This is not an improvement.
> Victor Zverovich has independently come to the same conclusion:
> https://twitter.com/vzverovich/status/1333111364357746690
I'm not sure if that was the wrong link or if you're referring to
something non-obvious to me there, but that doesn't appear related.
You may still have to choose the type between Boost and a C++ standard
alternative and no matter which type you choose the end-user may be
using the other type in his code and be irritated that you are not using
the type he is using.
> For example rather than
>
> unsigned int string_hash( const std::string s &) {...}
>
> I would use
>
> unsigned int string_hash( const std::string s &) const {
> return string_hash( s.c_str() );
> }
>
> Of course making this change after the fact would be quite a bit of
> work. But since I do it from the beginning, it's no extra work at all.
> And it eliminates many, many problems including the one described
> above. It's gotten to the point that for me, non constant parameters
> parameters are code smell. I almost never use them. And when I do,
> usage is almost always confined to member functions.
>
> I'm aware that this is actually off topic so sorry for hijaking the
> thread. But I believe that a lot of this (and other discussions),
> rather than trying to address problems with reconciling boost and std
> libraries would (mostly disappear) if users would step back and think
> more about what functional program can mean in the real world.
I only used #define to mimic the original example. You are correct that
a typedef or type alias is the right way. In cxx_dual 'cxxd_array'
becomes the correct namespace, rather than 'std' or 'boost' and the
programmer can go from there.