Boost logo

Boost :

From: Ivan Matek (libbooze_at_[hidden])
Date: 2024-12-19 20:12:52


On Thu, Dec 19, 2024 at 6:41 PM Vinnie Falco via Boost <
boost_at_[hidden]> wrote:

> I am in fact arguing that preferring the member function over the free
> function is incorrect. Free functions are objectively better than member
> functions. It doesn't matter how users feel, we have to design for the
> current rules of the language. I also think UFCS is a poor solution to this
> non-problem.
>

I am not sure what you mean by current rules of the language. There is no
such thing in this case since language allows both.

If you are talking about what experts prefer in terms of design situation
is the following:

According to Herb UFCS was close to being standardized so it seems a lot of
people want to fix what you call non-problem:
*2014-2016, which nearly reached plenary consensus*

Herb and Bjarne support UFCS. Ville opposes it because of silent breakages
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3027r0.html>,
meaning his opposition is unrelated to our comparison of member function vs
free function.
Herb explicitly prefers member functions in his paper, I would assume
Bjarne feel the same, but did not find anything specific.

Core guidelines initial reading seem to support free functions since try_at
can be implemented as free function
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c4-make-a-function-a-member-only-if-it-needs-direct-access-to-the-representation-of-a-class
but they have exception that mentions nice chaining so I would say they do
not have opinion on try_at case.

Barry Revzin(that is probably one of most active people in WG21) post says
he prefers member function.

*On the minus side, I find more and more that this API is pretty lacking in
both ergonomics and functionality.The goal of this post is to argue what’s
missing the lookup and insertion APIs, and what we can hopefully improve
upon.*

I would guess Scott Meyers would agree with you, but hard to know without
asking him.

Regarding standardization:
as mentioned before Herb claims that addition of free functions is not
because they are better than member functions, but because certain types do
not have members, so this is only way generic code can operate on types
easily.

as mentioned before starts_with have been added to string and string_view

member functions ssize() were removed after some opposition
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1227r2.html
I personally do not consider this a big strike against try_at since ssize()
is not such an important utility helper as try_at.

all monadic operations on std::optional are member functions, no need for
them to be members unless I am missing something.

std::expected proposal wanted free funciton for value_or
*This function is a convenience function that should be a non-member
function for optional and expected, however as it is already part of the
optional interface we propose to have it also for expected.*
I presume all 3 authors agree with this statement, one of them is Jonathan
Wakely from libstdc++ fame.

p1759r1
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1759r1.html> has
a poll where discussion was about member function vs free function for that
proposal and initial free function proposal got changed to member function.
Unclear if it relates to try_at since
from what I presume they were discussing closed set of types.

Regarding boost:
try_at in Json is not really helpful in this discussion since it uses
custom errors, so no generic free function is possible

Boost.Optional monadic member function
<https://www.boost.org/doc/libs/1_87_0/libs/optional/doc/html/boost_optional/quick_overview/monadic_interface.html>
could all be implemented as free functions unless I am missing something.
That would also work on std::optional and any other optional type that
satisfies same concept.

hash2 uses free function hash_append

// ... many other libraries in boost that I presume use both styles

Regarding "users":
Herb in his paper shows use of .begin() is much more common than
std::begin, not sure how applicable is this to this discussion, but in
general this has been me experience with coworkers,
they all prefer members, expect for symmetric functions like max.

As for your other arguments: I agree with all the downsides you mentioned(
all points from 1. inclusive to 5. inclusive) but I do not believe the
downsides outweigh the nicer API benefits.

On Thu, Dec 19, 2024 at 7:49 PM Vinnie Falco via Boost <
boost_at_[hidden]> wrote:

> If we want field experience, it is
> better to implement it as a separate free function to figure out buy-in and
> then later consider adding it as a member function.
>
> Issue is that you can not distinguish why are people not using it in that
case. I am pretty sure it would not be popular. For example I for sure
would not use it since I consider member find nicer api.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk