
On Fri, 20 Dec 2024, 22:58 Christian Mazakas via Boost, < boost@lists.boost.org> wrote:
On Fri, Dec 20, 2024 at 11:37 AM Neil Groves
wrote: As you know I've tried seeing how far I could get with some work in Boost.Range. I appreciate this isn't the solution you are dreaming of.
...
I wondered if reading this example line above if it didn't look quite as
horrific as perhaps you were imagining?
One unfortunate aspect of the original snippet is the boost::optional choice of the word "map" where we are also working with a concrete "map" container.
There is plenty of work to do if this is of interest to anyone. I would want to ensure there was no performance overhead, and currently I'm not entirely convinced that my initial implementation that uses the member equal_range is optimal. This is an implementation detail, which I would work through.
The value_or ( or front_or ) functionality for non-multi containers can be added in a similar manner, and be broadly usable for range algorithms. ... If this is of any interest to you I'll look at putting some of this into the develop branch of Boost.Range. If it is not interesting I shall continue on my branch and build a more compelling iteration that I shall land later.
I hope this helps
Fwiw, I don't mean to be a hater and I'm happy you're not discouraged.
I am discouraged by how long it took me to recognising the signs that no outcome would have been satisfactory other than total unconditional agreement with the original proposition. The find operation often wants the power of the iterator, but then other times a query like "at" that doesn't throw would be useful. I thought the find, tolerating absence, was your motivating use-case.
It's like I said, I don't actually have a strong opinion here either way.
I'm with Andrey, I think the iterator API *is* the useful API. Typically, when I find something in a map, I'll either erase or do something else where reusing the iterator is a key part of everything.
I would not take away the iterator idiom. It has proven to be extremely powerful.
My whole thing was about what users actually wanted vs all the costs of everything else.
In C++, we have basically unlimited power so we can honestly do basically whatever we want.
I think most users just want `try_find() -> optional
`, with `std::optional` and not Boost. Boost is okay as a polyfill, but users have told us ad nauseum that in 2024, they prefer STL versions.
This is a Boost mailing list. I assumed you wanted to see what we thought and could achieve and use what was learned. If the users now only want std ( these users seem to change their requirements very frequently ), what was it you wanted from the irrelevant boost developers? By showing changes in Boost.Range I hoped to make Boost.Range more useful and assumed similar changes could be made to std ranges. The header includes for boost range are not huge and so far do not require optional of either flavour. I have shown that by changes to range it can be achieved. The std ranges can do all that I have done in Boost.Range by way of example. I accept there may be issues with the std range header overhead, but consider that something fixable.
Second, I think the burden on users to opt into the perfectly generic version is too much for the little we're actually doing.
The header overhead is hundreds of lines less than your proposal with optional. My bias is to reducing the duplications, fixing the abstractions to be small and orthogonal and fixing the headers to have more and smaller files. The excessive header include overhead is partly due to a failure to decompose the problems. The include of optional adds more overhead than the include of the range map adapter. My implementation shows it can be implemented in just a few lines of code. Less overhead than including optional. And my solution only requires including the range adapter if you use it. Your solution requires every map header to include optional even if the feature is not used. My solution is more general, less intrusive, and has less header cost than the original proposal. Even the target syntax was largely approximated. My self assessment is that this works well for my understanding of the expressed requirements. I was surprised this is not an attractive option but fully accept it isn't what you want.
For a user to now get the behavior they want, they'll have to depend on Boost.Range, include the Range headers and then setup their functional pipeline just to do something that could've been this:
for (auto& user : users_map.try_find(user_id)) { user.status = deactivated; }
Yes for Boost.Range they need to include the relvant Boost.Range adaptor header. A similar adapter could be added to the std. To use optional you would have to include optional. The adapter header is considerably smaller than the optional header but for some reason including a smaller file is unacceptable overhead.
To this end, the user doesn't have to include anything more than `
`, which they would already have. The cool thing about Boost is that we're supposed to innovate and that means trying new things. I'm not saying Range-ifying everything is bad and
It was always a range, the most relevant function is even called equal_range. The map is already a range and the selected subset via a key is naturally a range for single and multi associative containers. What was done was not rangifying everything. It was continuing with ranges avoiding option-ifying the solution. The going in and out of optional is pointless additional overhead most of the time introducing opportunity for error. You were right to choose the optional::map member function in your final example as the safest solution. This good choice made it clear that the optional was neither necessary nor desirable for this specific use-case. I'm happy you're giving serious efforts into making it happen.
I'm just trying to give my opinion about the potential reception of such efforts. It's fine on paper but I'm not sure we have users clamoring for the feature to manifest in this way.
Having produced something that works, builds in less time, almost matching your syntactic ideal, and provides solutions for other contexts I expected users would be more happy with this solution. You clearly have unique access and understanding of the users requesting the original change. If std ranges header is too bloated it could be split in a similar manner to Boost.Range. The include demonstrably need not be as high overhead as optional, when implemented appropriately.
I'd be happy to be proven wrong.
- Christian
I shall park the branch, assess the changing landscape including Range V3 and see if anything useful can be contributed. I regret the noise I have made on the list. I genuinely have little understanding of what you want, fully accepting my part in my lack of comprehension. I will bow out from trying to help with this request. Perhaps another Boost developer will succeed in understanding the issues and context better, yielding a more agreeable result. I hope you get what you want and one day I will understand this all better. The best thing I can do for you at the moment is get out of the way. Regards, Neil Groves