Re: [boost] Please don't define a fake "operator <" justfor orderedcontainers

----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Peter Dimov Sent: 11 July 2006 11:18 To: boost@lists.boost.org Subject: Re: [boost] Please don't define a fake "operator <" justfor orderedcontainers
Daryle Walker wrote:
[1] If you make a fake order for "std::complex<>", would you compare real components then imaginary components, or would you use magnitude then angle?
Real, then imaginary. Compare with:
Interesting. I would have chosen magnitude and then angle. Why components.
"If you make a FAKE order for std::string, would you compare left to right or right to left?"
I don't think that is a legitimate comparison. In my world view, strings have a natural order but complex numbers don't. Now admittedly, operator <() for std::string doesn't actually correspond to my natural ordering (Zoë should be less than Zoo, but it isn't), but it is close enough for most purposes and much cheaper than a locale sensitive comparison. -- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 203894

Martin Bonner wrote:
----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Peter Dimov
Daryle Walker wrote:
[1] If you make a fake order for "std::complex<>", would you compare real components then imaginary components, or would you use magnitude then angle?
Real, then imaginary. Compare with:
Interesting. I would have chosen magnitude and then angle. Why components.
There are two reasons for that. First, composite types use lexicographical ordering by default, and std::complex is (de facto) a (real, imag) pair. Second, the magnitude/angle ordering has the property that if you have three numbers a, b, c, where a and b are very close to one another but not to c, it is possible to have a < c and c < b.
"If you make a FAKE order for std::string, would you compare left to right or right to left?"
I don't think that is a legitimate comparison. In my world view, strings have a natural order but complex numbers don't.
Possibly. So you define "fake" as "unnatural", and define "natural" as "feels natural to me". This approach can work but it's a bit subjective, isn't it? Consider the progression: complex<double> struct { double x, double y; } pair<double, double> tuple<double, double> vector<double> vector<char> string If we take the "feel" of operator< out of the equation, where should we draw the line, and based on what?

Le mardi 11 juillet 2006 à 14:21 +0300, Peter Dimov a écrit :
Daryle Walker wrote:
[1] If you make a fake order for "std::complex<>", would you compare real components then imaginary components, or would you use magnitude then angle?
Real, then imaginary. Compare with:
Interesting. I would have chosen magnitude and then angle. Why components.
There are two reasons for that. First, composite types use lexicographical ordering by default, and std::complex is (de facto) a (real, imag) pair. Second, the magnitude/angle ordering has the property that if you have three numbers a, b, c, where a and b are very close to one another but not to c, it is possible to have a < c and c < b.
Your reasoning is a bit flawed, since this property is also true for the lexicographic order. I assume that by "close" you mean with respect to the natural distance on the complex numbers. Then a = (1,0) and b = (2,0) are close (distance 1), yet c = (1.5,1e100) (distance ~1e100 from both a and b) is lexicographically between the two of them.
"If you make a FAKE order for std::string, would you compare left to right or right to left?"
I don't think that is a legitimate comparison. In my world view, strings have a natural order but complex numbers don't.
Possibly. So you define "fake" as "unnatural", and define "natural" as "feels natural to me". This approach can work but it's a bit subjective, isn't it?
Consider the progression:
This is not a progression. You can use vector<double> instead of struct{}, since struct{} is nothing more than a cartesian product while vector is a word monoid. But you can't use struct{} instead of complex<double>. This change would lose the whole point of complex<double>. It is supposed to (approximately) represent an algebraically closed field with characteristic 0.
complex<double> struct { double x, double y; } pair<double, double> tuple<double, double> vector<double> vector<char> string
Any set of computer data can be ordered. I don't think it means that they should all have an operator<. Best regards, Guillaume

Guillaume Melquiond wrote:
Le mardi 11 juillet 2006 à 14:21 +0300, Peter Dimov a écrit :
Interesting. I would have chosen magnitude and then angle. Why components.
There are two reasons for that. First, composite types use lexicographical ordering by default, and std::complex is (de facto) a (real, imag) pair. Second, the magnitude/angle ordering has the property that if you have three numbers a, b, c, where a and b are very close to one another but not to c, it is possible to have a < c and c < b.
Your reasoning is a bit flawed, since this property is also true for the lexicographic order.
Yes, you and Martin Bonner are right, and I am wrong on that.
complex<double> struct { double x, double y; } pair<double, double> tuple<double, double> vector<double> vector<char> string
Any set of computer data can be ordered. I don't think it means that they should all have an operator<.
Yes of course. So which types should have an operator< and which should not?

Le mardi 11 juillet 2006 à 15:34 +0300, Peter Dimov a écrit :
Any set of computer data can be ordered. I don't think it means that they should all have an operator<.
Yes of course. So which types should have an operator< and which should not?
In my humble opinion, only types which model mathematical types for which mathematicians have defined a "natural" order. For example, std::complex types model the complex numbers which do not have a natural ordering. std::vector types model the word monoids which have a natural ordering (the lexicographic one) as long as the base type is totally ordered. But this point of view only gives a small intuition. Sometimes it may be difficult to take a decision. For example, if you consider that std::set types model typed sets, then they should not have an operator<. But as a matter of fact they don't (in the STL): they model ordered typed sets, so it is not clear anymore that operator< should not be defined for them. Back to the topic of operator< for smart_ptr, I think it was a mistake for the STL to use std::less as the default parameter for ordered containers. It would have been better to define some kind of total_order template class (that would have defaulted to being std::less). For smart_ptr, the situation would then be clear: no operator< but a specialization of total_order. With respect to the current STL, I don't have a strong opinion on whether smart pointers should define or not operator<. Best regards, Guillaume

Guillaume Melquiond wrote:
Back to the topic of operator< for smart_ptr, I think it was a mistake for the STL to use std::less as the default parameter for ordered containers. It would have been better to define some kind of total_order template class (that would have defaulted to being std::less).
I agree that the inclusion of a separate "set/map order" relation in the standard library (that is defined for all standard value types) would have made the correct choice obvious.

On 7/11/06 10:54 AM, "Peter Dimov" <pdimov@mmltd.net> wrote:
Guillaume Melquiond wrote:
Back to the topic of operator< for smart_ptr, I think it was a mistake for the STL to use std::less as the default parameter for ordered containers. It would have been better to define some kind of total_order template class (that would have defaulted to being std::less).
I agree that the inclusion of a separate "set/map order" relation in the standard library (that is defined for all standard value types) would have made the correct choice obvious.
Maybe the committee should have gone the other way, by not providing a default argument for the comparison template parameter. (The "total_order" class template wouldn't be made either.) Then there wouldn't be an expectation that "<"/less is a blessed operation and all types must provide it at all costs. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (4)
-
Daryle Walker
-
Guillaume Melquiond
-
Martin Bonner
-
Peter Dimov