Proposal: Ternary comparison operator #8643
Replies: 37 comments
-
It was noted that there is a NuGet package which uses an extension method and some overloaded operator chicanery to mimic this language feature: dotnet/roslyn#136 (comment) However, if the compiler will only treat this expression as a range comparison if it wouldn't otherwise compile then I would imagine any existing code that might rely on this package would continue to compile and work as expected. But it should probably be included as a part of the test suite to ensure no unintended breaks. |
Beta Was this translation helpful? Give feedback.
-
Good to know. This would fall under the portion of the design of: we will existing semantics and always interpret that way if it succeeds. We only use the new semantics if it doesn't. That example is also interesting in that it's trying to provide these semantics. So a great part about this is that once we have this feature, you can stop using that lib :) |
Beta Was this translation helpful? Give feedback.
-
How would this be defined to avoid making further changes to binding not overly complex? For example if C# adds increases the number of places implicit operators can be used in the future, or changes lookup, or improves overload resolution, we would need to make sure all those things run only after we check if it matches this new ternary comparison operator. This might force the binding code to become very contorted to allow this. |
Beta Was this translation helpful? Give feedback.
-
honestly, i would say: given an tree of the form
We have the existing rules. We then have a clause htat says that if that produces an error (which we use terminology for in lambda-resolution) then rebind with such-and-such expected semantic rewrite. In general we discuss validity, and binding-time errors. This would apply here. If the normal interpretation results in an invalid (or binding-time-error), we try the new interpretation. I'm not sure any of the cases mentioned so far necessary matter. Or, if they do, they are starting to get to the cornerest corner of all corners :) |
Beta Was this translation helpful? Give feedback.
-
Linking back to my comment here #4106 (reply in thread) Since you're going to deal with some semantic ambiguities anyways, the postfix pattern does seem to be a viable alternative, except that there will be syntax ambiguities instead (but not in any useful scenarios mentioned here). Opened a new discussion: #4110 |
Beta Was this translation helpful? Give feedback.
-
Can there be a warning wave when bindinh to the old behavior? |
Beta Was this translation helpful? Give feedback.
-
I don't see any point in doing that |
Beta Was this translation helpful? Give feedback.
-
There may be some ambiguities need to be resolved, such as |
Beta Was this translation helpful? Give feedback.
-
Wouldn't this potentially break compatibility? Those operators are not guaranteed to represent comparisons. the user is free to give them different semantics. |
Beta Was this translation helpful? Give feedback.
-
This would have to be under a feature flag, so that the change in semantic doesn't change errors in previous version. Can work just via the binder and lowering.
I wrote that nuget package. Note it use |
Beta Was this translation helpful? Give feedback.
-
Compatibility concerns are fully addressed in the OP, no? |
Beta Was this translation helpful? Give feedback.
-
No. The specification can effectively be read to say: If this has legal semantics under C# 9. The use those semantics. Othewise, try the new semantics. So nothing can break. |
Beta Was this translation helpful? Give feedback.
-
OP doesn't mention if |
Beta Was this translation helpful? Give feedback.
-
Your package will retain its semantics. |
Beta Was this translation helpful? Give feedback.
-
We have <= and => today, tell me they are the same thing. |
Beta Was this translation helpful? Give feedback.
-
What ambiguity is in that fragment? Creating the parse tree for that is not ambiguous so far as I can see. |
Beta Was this translation helpful? Give feedback.
-
It would need appropriate lookahead to ensure that generics, variables, and comparisons were properly handled. It's likely not a full ambiguity, but a local one. |
Beta Was this translation helpful? Give feedback.
-
Is it |
Beta Was this translation helpful? Give feedback.
-
Yes I see that when there's no context, but in the case of an A declaration isn't legal (well I can't see it myself) inside the expression that's part of an C# seems to already parse this correctly too: int A = 0;
int B = 0;
int C = 0;
int D = 0;
int F = 0;
if (A<B<C>D>F)
{
;
} The diagnostic it reports is not about syntax but a semantic problem, the types that are used either side of the operator This too suggests that if the semantic checking were replaced, the expression interpreted as a chained compare, it would work. |
Beta Was this translation helpful? Give feedback.
-
As far as I can test, the compiler is already happy with that syntax |
Beta Was this translation helpful? Give feedback.
-
Yes. This is an example of us addressing the potential issue. The situations brought up are there so we ensure we think through it and make sure the language is spec'ed such that it is not an issue and so that the compiler operates as expected with appropriate tests. |
Beta Was this translation helpful? Give feedback.
-
I really don't understand this. There is also ambiguity with another ternary operator |
Beta Was this translation helpful? Give feedback.
-
What ambiguity are you referring to?
No one said we are not fine with ambiguities... As i said in the post above yours, we would just need to be cognizant so we can spec hte language out properly, and ensure the compiler does the right thing. |
Beta Was this translation helpful? Give feedback.
-
what does a? b? c: d: do and what does a < b < c < d do. both ambiguous . () needed to fix this |
Beta Was this translation helpful? Give feedback.
-
The code is incomplete and will be a failure to parse. Did you miss a Assuming it's accidental, and you meant: Can you please clarify? |
Beta Was this translation helpful? Give feedback.
-
Currently it is syntactically legal, and may have semantic meaning in esoteric cases. This proposal discusses giving it legal meaning in the case where it is illegal today. |
Beta Was this translation helpful? Give feedback.
-
Random concerns:
|
Beta Was this translation helpful? Give feedback.
-
My thought here is that this is shorthand for
Looks like the space for an optimization pass, or an analyzer message. Not really in scope for the language itself.
That seems reasonable. We already do constant analysis and requisite flow control for similar htings today: So this could similarly evaluate to always being false (if 'a' is an integer of course). |
Beta Was this translation helpful? Give feedback.
-
C++ is also looking to add this; albeit with disallowing the potentially ambiguous forms like |
Beta Was this translation helpful? Give feedback.
-
Ternary comparison operator
Summary
This would allow users to write a simplified
x < y < z
test as shorthand forx < 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:
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
, whereop1
andop2
are one of>
,<
,>=
,<=
is reinterpretted as: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.Design meetings
Beta Was this translation helpful? Give feedback.
All reactions