Deutsch   English   Français   Italiano  
<87sexoy417.fsf@nosuchdomain.example.com>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith Thompson <Keith.S.Thompson+u@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: Interval Comparisons
Date: Fri, 07 Jun 2024 11:57:24 -0700
Organization: None to speak of
Lines: 109
Message-ID: <87sexoy417.fsf@nosuchdomain.example.com>
References: <v3merq$b1uj$1@dont-email.me>
	<pan$63fde$3c88716e$c61af1ee$d0a27c97@invalid.invalid>
	<v3o706$kfrm$2@dont-email.me> <v3o7jr$ki9u$1@dont-email.me>
	<v3of4h$pbb1$1@dont-email.me> <v3t0aa$1k8ck$2@dont-email.me>
	<v3tene$1n5ge$1@dont-email.me> <v3tlkj$1of9j$1@dont-email.me>
	<v3tqji$1t2fv$1@dont-email.me>
	<87bk4dz9ve.fsf@nosuchdomain.example.com>
	<v3ujg5$20s0s$1@dont-email.me>
	<87wmn1xek8.fsf@nosuchdomain.example.com>
	<v3upg2$21i37$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Fri, 07 Jun 2024 20:57:25 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="3ec284f1a7e8071e4d0b56ae14cf643f";
	logging-data="2301114"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1++l4tifBbVBuTfYGhNGPhM"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:iRWwGNz5jw1kJ3SeGVOoP3XqyEE=
	sha1:+y2yxxroiBjIIACpf4eQLBbLFaQ=
Bytes: 6791

David Brown <david.brown@hesbynett.no> writes:
> On 07/06/2024 11:55, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 07/06/2024 05:53, Keith Thompson wrote:
>> [...]
>
>> 
>>> There is also the C++ compatibility question.  C++ provides flexible
>>> operator overloading combined with a poverty of available operators,
>>> so the relational operators <, >, <= and >= are sometimes used for
>>> completely different purposes, similar to the >> and <<
>>> operators. Chaining relational operators would complicate this
>>> significantly, I think.  If C++ adopted the feature it would be a mess
>>> to support overloading, and if they did not, "a < b < c" in C and C++
>>> would be valid but with completely different semantics.  Neither
>>> option is good.
>> I mentioned earlier that someone did a study of open source C++ code
>> and
>> found no occurrences of things like "a < b < c", except for 4 cases that
>> were intended to be chained but would behave incorrectly.  I presume
>> that this study would have covered overloaded operators.
>> 
>
> You helpfully quoted from that study, and it included :
>
> - Many instances of using successive comparison operators in DSLs that
>   overloaded these operators to give meaning unrelated to comparisons.
>
> So yes, it seems that overloading the relational operators for other
> purposes and then chaining them is a real thing.
>
>>> To me, this possibility, along with the confusion it would cause,
>>> totally outweighs any potential convenience of chained comparisons.  I
>>> have never found them helpful in Python coding, and I can't imagine
>>> them being of any interest in my C code.
>> I agree.  I wouldn't mind being able to use the feature, and I think
>> I've actually used it in Python, but its lack isn't a big problem.
>> 
>>> Even in a new language, I would not want to see chained relational
>>> operators unless you had a strict requirement that relational
>>> operators evaluate to a boolean type with no support for relational
>>> operators between booleans, and no support for comparison or other
>>> operators between booleans and other types.
>> In Python, all comparison operators (<, >, ==, >=, <=, !=, is, is
>> not,
>> in, not in) have the same precedence, and chained operations are
>> specified straightforwardly.  They evaluate to a bool result.  Boolean
>> values can be compared (False < True), which doesn't seem to cause any
>> problems.
>> https://docs.python.org/3/reference/expressions.html#comparisons
>> 
>>>                                               And even then, what is "a
>>> == b == c" supposed to mean, or "a != b != c" ?
>> "a == b && b == c", and "a != b && b != c", respectively, except
>> that b
>> is only evaluated once.
>> 
>
> If "c" is a boolean, some might think the "natural" interpretation of
> "a == b == c" is "(a == b) == c" - it is the current semantics in C.
> Some people may think that "a != b != c" should be interpreted as "(a
> != b) & (b != c) & (a != c)".

Yes, some people might be wrong.

> It's one thing to make a rigid definition of the meaning in a
> language, picking a consistent set of rules of precedence and syntax.
> It is another thing to make sure it matches up with the
> interpretations people have from normal mathematics, natural language,
> and other programming languages.  When there is a mismatch, you need
> good reasons to accept the syntax as a good language design idea - the
> more likely the misunderstanding, the stronger reasons you need.
>
> To me, the potential misunderstandings of including != in chains is
> far too high in comparison to the meagre benefits.  The use of ==
> could be clear in some situations (combined with strong type checking
> to help catch mistakes) but not others.  I could see a chain of a mix
> of < and <= making sense, or of > and >=, and occasionally being
> useful.  I don't think there is a point in allowing more than that.
>
> After all, if all you need is to avoid evaluating "b" more than once,
> you can just do:
>
> 	auto const b_ = b;

There are two separate issues here.

One is adding chained comparisons to C.  We both agree that this is
impractical because it would silently change the meaning of valid code.
(Changing the meaning of old code isn't likely to be much of an issue,
but any new code using the feature would quietly change behavior when
compiled under older C standards or when ported to C++.)

The other (arguably off-topic) is providing chained comparisons in other
languages.  Python does this well, in my opinion.  All comparison
operators have the same precedence, and the semantics of chained
comparisons are defined straightforwardly.  There are no arbitrary
restrictions, so you can write things that some people might find ugly
or confusing (if you have a language that bans ugly code, I'd like to
see it).  The meaning of `a =< b > c` or `a != b == c` is perfectly clear
once you understand the rules, and it doesn't change if any of the
operands are of type bool.  `a != b != c` *doesn't* mean
`a != b and a != c and b != c`.  (If you want to test whether all three
are unequal to each other, you can write `a != b != c != a`, though that
evalutes `a` twice.)

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */