C++ Logo

std-discussion

Advanced search

Re: The unnecessary confusion of the C++23 proposal P0847R6

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sat, 31 Jul 2021 10:25:09 -0400
On Fri, Jul 30, 2021 at 5:19 PM Hani Deek via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> Recently I have seen the C++23 proposal P0847R6 ("Deducing this").
> When I first started reading that paper, I felt happy, because I thought that the authors were proposing a new, more powerful syntax to define non-static member functions.
> However, as I finished reading the paper, my initial happiness had turned into dismay. The paper does not really propose a new syntax for non-static member functions. Instead, it proposes to add to the C++ language a new kind of member functions besides the existing two kinds, the static and non-static member functions.
>
> The proposed new type of member functions awkwardly merges characteristics of both static and non-static member functions. It can be called with the member-of-object operator like a non-static member function, but it has the type of a static function.
> If this paper gets approved, which I doubt it will, it will complicate the C++ language and make it more confusing for no real gain.
> All the real benefits of this proposal can be obtained simply by introducing a new syntax for the non-static member functions. There is no need to add to the language a new hybrid kind of member functions.

OK, so what would this "new syntax" look like?

The nice thing about this proposal is that, if you already understand
how the language works, you can quickly understand the new feature.
C++'s rules for overload resolution, template argument deduction, and
the like are all the same. The only thing you have to learn really is
that if a member function has a `this` in its first parameter, then it
is effectively `static`, but can be called as if it were non-`static`.

So where does this distinction actually *matter* to either the writer
of such a function or its user? It really only matters if you are
trying to get a pointer to the member itself. In all other cases, you
can just treat it like a regular non-`static` member function. It
looks like a non-`static` member, and it acts like one almost all the
time.

Your hypothetical "new syntax for the non-static member functions"
would be a novel syntax whose properties would need to be learned.

> The only thing in the paper that is impossible to do with the regular non-static member functions is to pass the object parameter by value. But what is the importance of this feature?

The primary impetus is to allow you to have the object parameter be a
template parameter of a member function, thus allowing it to be
`const`, `&`, `&&`, etc using the existing rules. The very first
example in the paper is of our existing mechanisms to avoid
duplication for when you have an `operator[]` that needs to return
`const&` or `&` depending on whether `this` is `const` or not. The
current solution is an ugly hack. This only got worse with `&&` vs.
`&` qualifiers.

As a consequence of the way they went about implementing this
behavior, they *also* get the ability to pass the object parameter by
value (or reference) rather than just by pointer. But that wasn't
really the point of the feature.

> It hardly has any importance. It certainly does not justify the complicated and confusing proposal of this paper.
> I suggest that the authors take a look at the feature called "extension methods" of the C# language. That feature is very close to their proposal, but it is formulated in a much better and cleaner way. The extension methods of C# are ordinary static functions that can be defined anywhere, not necessarily in a class scope. They differ from the other static functions only in that they can be called with the member-of-object operator like non-static member functions. Since they are static functions, they can take the object parameter by value. This system is good because it keeps the distinction clear between the static functions and the non-static member functions. There is no confusing hybridization as proposed in the paper.

"Extension methods" are basically a form of a long-running idea in C++
called "unified function call syntax" (UFCS): the ability to
effectively add to a class's member interface from outside of the
class.

UFCS had a large number of proposals for it in the C++17
standardization era. Some proposed UFCS as a way to make member
functions be called as if they were non-members, others proposed
having non-members be called as if they were members, and others were
more hybridized. The committee iterated on the concept in numerous
ways, looking at different syntax, whether it was opt-in or opt-out,
etc.

*All of them* failed to gain consensus. At this point, the committee
seems to have given up on it.

This proposal is specifically trying *not* to do UFCS stuff. It's
specifically intended to be a way of writing a member function of the
class.

> In my opinion, this paper should be split into two. One paper should propose an alternative syntax for the already existing non-static member functions, and another should propose a new kind of static functions similar to the "extension methods" of C#. That way, we keep different things clear and distinct.
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion

Received on 2021-07-31 09:25:24