Clarifying std::strong_ordering and std::stong_equality semantics in P0515 R3

62 views
Skip to first unread message

len...@gmail.com

unread,
Oct 26, 2018, 8:20:40 AM10/26/18
to ISO C++ Standard - Future Proposals
Hi,

I think the semantics of the strong_* return types for the starship operator need some clarification for heterogeneous comparison. The proposed "substitutability" semantics in P0515 R3 only works for homogeneous comparison (i.e. for strong equality a == b implies f(a) == f(b) for every function f).

I propose the following for strong equality semantics for heterogeneous comparison:

For every a,b of type A and c of type B if a == c and b == c, then for every function f f(a) == f(b). And for every x of type A and y,z of type B if x == y and x == z, then for every function g g(y)==g(z).

One example of strong comparison between different types is case sensitive string comparison between different string types. Maybe others can come up with other examples.

Best regards,
Lénárd Szolnoki

Tony V E

unread,
Oct 26, 2018, 8:59:54 AM10/26/18
to Standard Proposals
On Fri, Oct 26, 2018 at 8:20 AM <len...@gmail.com> wrote:
Hi,

I think the semantics of the strong_* return types for the starship operator need some clarification for heterogeneous comparison. The proposed "substitutability" semantics in P0515 R3 only works for homogeneous comparison (i.e. for strong equality a == b implies f(a) == f(b) for every function f).

I propose the following for strong equality semantics for heterogeneous comparison:

For every a,b of type A and c of type B if a == c and b == c, then for every function f f(a) == f(b). And for every x of type A and y,z of type B if x == y and x == z, then for every function g g(y)==g(z).


Does that definition work well if A is CaseINsensitiveString and B is string?
What about vice-versa?

Concepts uses a different definition (see EqualityComparableWith, and note for concepts, there is only *strong* equality, it never deals with weak equality).

The Concepts definition is basically find a common-type between A and B, call it C.  Every a,b,c,...x,y,z of A and B are converted to C (ie via constructor) and then == is done via C.
If C's == is strong, than A == B is strong.

This also follows the idea that a type is an attempt to model some _value_, where the true value often outside of C++.  Like int models numbers.  Like all date classes attempt to model the external concept of "date".  So MyDateClass and YourDateClass are equal when they both refer to the same external date.

The only question for the common-type definition is whether the common type needs to really exist in C++, or does it just need to theoretically exist.  Do we need a CommonDate type to do MyDate == YourDate, or is it enough that they refer to the same "platonic" date ideal.


One example of strong comparison between different types is case sensitive string comparison between different string types. Maybe others can come up with other examples.

Best regards,
Lénárd Szolnoki

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ef8c3389-636e-4fe6-b654-973ef10b2bde%40isocpp.org.


--
Be seeing you,
Tony

len...@gmail.com

unread,
Oct 26, 2018, 10:27:59 AM10/26/18
to ISO C++ Standard - Future Proposals
Hi,

Does that definition work well if A is CaseINsensitiveString and B is string?
What about vice-versa?

Assuming CaseInsensitiveString has strong equality with itself and you want operator==(CaseInsensitiveString, string) be case insensitive then yes, you can't return with strong_equality? Return with weak_equality in this case. Would CaseInsensitiveString and string even satisfy EqualityComparableWith?

I think it's strange that the definition of EqualityComparableWith needs a third common type for comparison, it's absolutely not needed. The common_reference requirements can be dropped and the following requirements can be added:

EqualityComparableWith<T, U> is staisfied only if given
  • a and b, lvalues of type
    const std::remove_reference_t<T>
    and
  • x and y, lvalues of type
    conststd::remove_reference_t<U>
the following is true:
!(bool(a == x) && bool(b == y)) || !(bool(a==b)^bool(x==y))

It's rather cryptic this way, but it basically says that the operator== between different types describes an isomorphism. No need for a common type. Then again, maybe the users of EqualityComparableWith need the common reference anyway and the above restriction can't be described in code.

Best regards,
Lénárd

Thiago Macieira

unread,
Oct 26, 2018, 2:02:47 PM10/26/18
to std-pr...@isocpp.org
On Friday, 26 October 2018 05:20:40 PDT len...@gmail.com wrote:
> I think the semantics of the strong_* return types for the starship
> operator need some clarification for heterogeneous comparison. The proposed
> "substitutability" semantics in P0515 R3 only works for homogeneous
> comparison (i.e. for strong equality a == b implies f(a) == f(b) for every
> function f).

A simple f that breaks for std::string:

const char *f(const std::string &s)
{
return s.c_str();
}

Two strings may be equal and yet have different data pointer addresses.

Does this mean "f" needs qualification too?

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center



Tony V E

unread,
Oct 26, 2018, 7:00:02 PM10/26/18
to Standard Proposals
On Fri, Oct 26, 2018 at 2:02 PM Thiago Macieira <thi...@macieira.org> wrote:
On Friday, 26 October 2018 05:20:40 PDT len...@gmail.com wrote:
> I think the semantics of the strong_* return types for the starship
> operator need some clarification for heterogeneous comparison. The proposed
> "substitutability" semantics in P0515 R3 only works for homogeneous
> comparison (i.e. for strong equality a == b implies f(a) == f(b) for every
> function f).

A simple f that breaks for std::string:

const char *f(const std::string &s)
{
        return s.c_str();
}

Two strings may be equal and yet have different data pointer addresses.

Does this mean "f" needs qualification too?

Yes it does.  You need to bring in the idea of "salient" attributes.  See Lakos http://wg21.link/N2479
Basically, address is not a salient part of the _value_ of string.



--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Reply all
Reply to author
Forward
0 new messages