Date: Sat, 23 Sep 2023 14:35:21 -0400
On Sat, Sep 23, 2023 at 2:13 PM Chris Gary via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> *move and forward can be defined without compiler hooks. This is where the
> language does not make architectural assumptions.*
> *typeid() cannot.*
>
Right.
In general: Architecture is disrupted when an unwanted or incompatible role
> is introduced or required by a dependency. All C++ applications are now
> dependent on the standard library [...] It must be possible to effectively
> use the language without the library.
>
I agree with you, as a general rule. But, as everyone's saying, you're
re-litigating a decision that was already made in
- C++20, with the type of `auto x = (1 <=> 2)` being std::strong_ordering
and the type of `auto x = (1. <=> 2)` being std::partial_ordering;
and that decision was merely in line with the decisions C++ made in
- C++20, with basically everything in coroutines;
- C++17, with structured bindings' being dependent on std::tuple_size and
std::tuple_element <https://eel.is/c++draft/dcl.struct.bind#4>;
- C++11, with ranged-for-loops' being dependent on
<https://eel.is/c++draft/stmt.ranged#1.3> the magic identifiers "begin" and
"end", and the type of `auto x = {1,2}` being std::initializer_list<int>;
- C++98, with the type of `auto x = typeid(int)` being std::type_info.
You can't invoke a general principle to undo a specific
three-years-out-the-door decision, especially when that decision is in line
with two-decade-old decisions.
Separately, it sounds like you don't appreciate the semantic difference
between std::strong_ordering and std::weak/partial_ordering, which *is*
actually used by the STL, such as std::vector and std::tuple. It's
important to the current definition of std::tuple's `operator<=>` that it
be able to compute the "common comparison type" of all its elements'
comparison types. So e.g.
decltype(std::tuple<double, int>() <=> std::tuple<double, int>()) is
std::partial_ordering
decltype(std::tuple<int, int>() <=> std::tuple<int, int>()) is
std::strong_ordering
If `operator<=>` just returned `int` all the time, we'd lose that
distinction. You might think that that distinction is okay to lose; but so
far you haven't even acknowledged that it *exists*, and that's a problem
for your position. You have to demonstrate that you know what the problem
*is*, before you offer (possibly over-simplified) solutions to it.
Btw, compare std::strong_ordering to std::nullptr_t. The former is a class
type; the latter is merely a type alias to some new fundamental type
<https://eel.is/c++draft/basic.fundamental#16> that was added to the
language in C++11. The latter seems to me like a better solution overall,
but, if we'd done that for the comparison types, we'd have had to add
*three* new fundamental types to C++. I think nullptr was probably worth
adding a new fundamental type for. I don't think comparison types were
really worth that (especially not x3). It was certainly *easier* to
standardize them as merely class types known to the compiler "by magic."
my $.02,
Arthur
std-proposals_at_[hidden]> wrote:
>
> *move and forward can be defined without compiler hooks. This is where the
> language does not make architectural assumptions.*
> *typeid() cannot.*
>
Right.
In general: Architecture is disrupted when an unwanted or incompatible role
> is introduced or required by a dependency. All C++ applications are now
> dependent on the standard library [...] It must be possible to effectively
> use the language without the library.
>
I agree with you, as a general rule. But, as everyone's saying, you're
re-litigating a decision that was already made in
- C++20, with the type of `auto x = (1 <=> 2)` being std::strong_ordering
and the type of `auto x = (1. <=> 2)` being std::partial_ordering;
and that decision was merely in line with the decisions C++ made in
- C++20, with basically everything in coroutines;
- C++17, with structured bindings' being dependent on std::tuple_size and
std::tuple_element <https://eel.is/c++draft/dcl.struct.bind#4>;
- C++11, with ranged-for-loops' being dependent on
<https://eel.is/c++draft/stmt.ranged#1.3> the magic identifiers "begin" and
"end", and the type of `auto x = {1,2}` being std::initializer_list<int>;
- C++98, with the type of `auto x = typeid(int)` being std::type_info.
You can't invoke a general principle to undo a specific
three-years-out-the-door decision, especially when that decision is in line
with two-decade-old decisions.
Separately, it sounds like you don't appreciate the semantic difference
between std::strong_ordering and std::weak/partial_ordering, which *is*
actually used by the STL, such as std::vector and std::tuple. It's
important to the current definition of std::tuple's `operator<=>` that it
be able to compute the "common comparison type" of all its elements'
comparison types. So e.g.
decltype(std::tuple<double, int>() <=> std::tuple<double, int>()) is
std::partial_ordering
decltype(std::tuple<int, int>() <=> std::tuple<int, int>()) is
std::strong_ordering
If `operator<=>` just returned `int` all the time, we'd lose that
distinction. You might think that that distinction is okay to lose; but so
far you haven't even acknowledged that it *exists*, and that's a problem
for your position. You have to demonstrate that you know what the problem
*is*, before you offer (possibly over-simplified) solutions to it.
Btw, compare std::strong_ordering to std::nullptr_t. The former is a class
type; the latter is merely a type alias to some new fundamental type
<https://eel.is/c++draft/basic.fundamental#16> that was added to the
language in C++11. The latter seems to me like a better solution overall,
but, if we'd done that for the comparison types, we'd have had to add
*three* new fundamental types to C++. I think nullptr was probably worth
adding a new fundamental type for. I don't think comparison types were
really worth that (especially not x3). It was certainly *easier* to
standardize them as merely class types known to the compiler "by magic."
my $.02,
Arthur
Received on 2023-09-23 18:35:34