Evaluating Ternary Statement - Proposal #1961
Replies: 23 comments
-
I see a total of two characters saved... I'm not getting what improvement this actually brings (esp. as it can't be used in an expression context).
Sure it does:
|
Beta Was this translation helpful? Give feedback.
-
This would become: |
Beta Was this translation helpful? Give feedback.
-
If you want a brief, single line form of 'if' you can just write:
This really doesn't seem to be saving much. Worse, it seems more confusing you have to read ahead to even know what's happening. 'if' clearly makes it clear that there is conditional flow and statement execution. |
Beta Was this translation helpful? Give feedback.
-
This is definitely very interesting to parse, and would be tricky to get right (not impossible though). For example, consider that
What's going on at thsi point? A ternary statement, starting with a binary expression? Or the start of a generic local function? :) |
Beta Was this translation helpful? Give feedback.
-
On a single line, you'd save 9 characters. In an entire project with thousands of lines of code, that can add up to both file size and time typing. Its much easier to quickly type
I'm not sure on the criticism here about reading ahead. Take the standard ternary operator example below: // You have to read ahead to know that it will be 100 if null..
var result = something ?? 100;
// You have to read ahead to know that it can be 10, or 100 if condition passes...
var result = condition ? 10 : 100
// My example, nothing new here nor against standards...
condition ? DoThingA() : DoThingB();
I'm not sure I follow your point here. In this following example we have both elements: bool? result = false;
result.Value ? DoSomething() : DoSomethingElse();
// Or if you are concerned about in-line, it would need to be encapsulated...
(bool? result = false).Value ? DoSomething() : DoSomethingElse(); |
Beta Was this translation helpful? Give feedback.
-
With an expression, i always know i have to look ahead :) |
Beta Was this translation helpful? Give feedback.
-
I'm saying: from a parsing perspective, this is complex. because when you have You have to try both routes, and determine which is correct, potentially unwinding and retrying to get it right. If this is a ternay-expression for example, then A.B.C.D is a bunch of This is not impossible to deal with. I was just addressing your point that:
This is not hte case. the |
Beta Was this translation helpful? Give feedback.
-
I'd rather have the structure of the |
Beta Was this translation helpful? Give feedback.
-
@dklompmaker wrote:
Code is read many more times than it is written - the overhead of having to puzzle through, working out whether this is a ternary expression, local function declaration or something else altogether, would very quickly overwhelm any savings based on having to type a few less characters. Further, while not all C# developers use Visual Studio, many do, and those folks can type |
Beta Was this translation helpful? Give feedback.
-
Your statement would be true if the parser doesn't hold any knowledge about previous tokens or sibling tokens. I'm pretty sure that the parser can determine between an assignment of a variable from a ternary operator vs. a ternary expression that isn't assigned to a variable.
I'm not an expert in the parsing that is occurring, however instead of looking ahead, you can simply look behind to determine whether a variable is being assigned. This is enough to determine whether to parse for ternary operation vs. evaluating ternary expression. // Parser knows that we are assigning to variable result...
var result = condition ? "hello" : "world";
// No assignment, therefore we can match against the evaluating ternary expression...
condition ? MethodA() : MethodB();
I appreciate your thoughts on this. I don't agree that it would be confusing to read. Take the following example that uses the different ambiguous cases being referenced. public void OnCompleted()
{
var resultOfLocalFunction = SomeLocalFunction();
// Variable assignment, so parser doesn't match on this case...
int? resultOfNullable = true;
// Again, a ternary returns a value thus doesn't match the expression...
var resultOfTernary = resultOfLocalFunction ? true : false;
// We are not assigning to a variable, thus evaluates the ternary statements.
resultOfLocalFunction ? DoTrueCallback();
// Local function that demonstrates that it's different than an evaluating ternary expression...
bool SomeLocalFunction()
{
return ...
}
} |
Beta Was this translation helpful? Give feedback.
-
Thanks for your feedback. I'm not suggesting we replace if/else. I'm suggesting that we provide an option for a shorter inline if/else syntax that developers can use. |
Beta Was this translation helpful? Give feedback.
-
I am :) But this isn't an argument by authority. I'm simply stating, with my actual experience working and developing the parsers for C# and TypeScript, that this is non-trivial. Again, not impossible, but not simple.
This is not sufficient. Again, the case is this: You have What follows the |
Beta Was this translation helpful? Give feedback.
-
// We are not assigning to a variable, thus evaluates the ternary statements.
resultOfLocalFunction ? DoTrueCallback();` This is very ambiguous to me. It looks like you're starting to declare a local function called |
Beta Was this translation helpful? Give feedback.
-
If
|
Beta Was this translation helpful? Give feedback.
-
It really isn't an expression because it returns nothing. It's a shorthand for if, if/else. I've renamed the proposal to statement to ensure that there isn't confusion.
I do see your point. To visualize this issue, let's create an example that would be ambiguous: public void SomeMethod()
{
// The concern is that this can be ambiguous to the parser...
SomeType? SomeInlineFunction()
{
....
}
// perhaps ambiguity...
var SomeType = new SomeType();
// Parse should expect a bool literal, or expression resulting in a bool...
SomeType != null ? DoMethodA() : DoMethodB();
} Now, if the parser cannot determine the type of the conditional expression, then I can see where there would be ambiguity. If this is truly an issue, we could enforce a spacing rule on the Take the string interpolation example of Or, alternatively we can define another character than |
Beta Was this translation helpful? Give feedback.
-
In general, parsers cannot tell this sort of thing. What you are describing is 'semantic directed parsing' and it's definitely not what Roslyn does (for very good reason). For one thing, it becomes nearly impossible to have any sort of incremental-parsing story because you need to know the semantics of the entire world around you to make decisions.
This would be a breaking change. Existing programs would break. We cannot restrict previously allowed constructs. :) |
Beta Was this translation helpful? Give feedback.
-
Agreed. I wasn't proposing this as an actual solution, but pointing out the lack of uniformity when it comes to tokens in the space. With |
Beta Was this translation helpful? Give feedback.
-
That's because hte 'token' there is the entire construct. When you have This is very common and normal in programming languages. In the case of |
Beta Was this translation helpful? Give feedback.
-
The language does not restrict what can go between tokens**. That's pretty much the definition of what a token is :) It's the building blocks that everything is created out of. By definition, trivia (whitespace, comments, etc.) are allowed between them. But trivia is only allowed between tokens. It's not allowed within a token itself. |
Beta Was this translation helpful? Give feedback.
-
Fair enough :) |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi |
Beta Was this translation helpful? Give feedback.
-
@dklompmaker Yes. That would work. but then we'd be down to: we already have a good unique tokens for this: |
Beta Was this translation helpful? Give feedback.
-
Also, But if you're really bothered by the cumbersome length of the code compared to the simple idea, and feel like putting it all on one line is wrong or whatever (it is), you can write an extension method: if (condition) MethodA(); else MethodB();
condition ?> MethodA() : MethodB();
condition.Select(MethodA, MethodB); And frankly, you can get this code even shorter than your example syntax if you can find a shorter word. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Evaluating Ternary Statement
Summary
Utilizing the work already in place for the ternary operator, we can further improve and simplify the language by adding Evaluating Ternary Statement.
Design
The form is very elegant and follows what we already know from ternary operators. In order to avoid ambiguity, the token takes the form
?>
.If Form
{condition} ?> {statement};
If / Else Form
{condition} ?> {statement} : {else_statement};
Criticism
Simply use if/else in-line
Of course, in the example for the single method execution, we can write:
If we were to write this with the proposed form, it would be 5 characters saved:
Beta Was this translation helpful? Give feedback.
All reactions