-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Ternary comparison operator
- Discuss this proposal here: Proposal: Ternary comparison operator #8643
Summary
This would allow users to write a simplified x < y < z test as shorthand for x < y && y < z.
Detailed design
This code is already parseable today and already has meaning. Indeed, here is a (albeit pathological) case where this would compile today:
using System;
public static class Program {
public static void Main() {
var (x, z) = (new C(), new C());
Console.WriteLine(x < 5 < z);
}
}
public struct C
{
public static bool operator <(C x, C y) => true;
public static bool operator >(C x, C y) => true;
public static C operator <(C x, int y) => x;
public static C operator >(C x, int y) => x;
}In order for this type of code to compile today, you'd need to do very strange operator overloading which would not be expected in practice. However, because of back compat, we would likely have to support this.
As such, when processing a binary expression of hte form expr1 op expr2 op expr3 we would have to bind in the same fashion as today. However, if that form failed to bind the operators successfully, we would now reinterpre the above as:
expr1 op1 expr2 op2 expr3, where op1 and op2 are one of >, <, >=, <= is reinterpretted as:
var __t1 = expr1;
var __t2 = expr2;
var r = false;
if (__t1 op1 __t2)
{
var __t3 = expr3;
if (__t2 op2 __t3)
r = true;
}
This should match intuition here and would mean code executes (including order of evaluation and short-circuiting) as expected.
Drawbacks
Potential confusion over a piece of code potentially having two different meanings. However, this is so unlikey as no real codebases should ever have been using a < b < c. It just isn't a reasonable code pattern today, so no one uses it or expects it to work the way it does today. Practically all users looking at this would expect it to have the semantics this proposal is suggesting.