The ternary operator is both left operative and right operative .. or none

QUESTION: If you understand this problem, explain to me what I do not see. My question is: how does the Trojan work? To clarify my question: what does legal associativity mean here? Why does associativity not coincide with the order of evaluation? This is clearly similar to the if else statement. It is not rated from right to left. It seems to me that I should be a legitimate associative.

I made a boolean to try and prove it. This shows me that this is not an associative association (I might not understand what associative law is). If it were correctly associative, it would work out so that was the answer that gave me:

"Because this statement is right-associative, your code works like:"

true ? false ? false ? false ? 3 : 4 : 5 : 6 : 7 evaluated as; true ? false ? false ? (false ? 3 : 4) : 5 : 6 : 7 which evaluated as; true ? false ? false ? 4 : 5 : 6 : 7 which evaluated as; true ? false ? (false ? 4 : 5) : 6 : 7 which evaluated as; true ? false ? 5 : 6 : 7 which evaluated as; true ? (false ? 5 : 6) : 7 which evaluated as; true ? 6 : 7 which returns 6. 

I tried to prove this, for example:

  int Proof = ternaryTrueOne() ? ternaryTrueTwo() ? ternaryFalseOne() ? ternaryTrueThree() ? ternaryFalseTwo() ? 2 : 3 : 4 : 5 : 6 : 7; static bool ternaryTrueOne() { Console.WriteLine("This is ternaryTrueOne"); return true; } static bool ternaryTrueTwo() { Console.WriteLine("This is ternaryTrueTwo"); return true; } static bool ternaryTrueThree() { Console.WriteLine("This is ternaryTrueThree"); return true; } static bool ternaryFalseOne() { Console.WriteLine("This is ternaryFalse"); return false; } static bool ternaryFalseTwo() { Console.WriteLine("This is ternaryFalseTwo"); return false; } 

In this case, it will be evaluated equally. Right? This means that trernaryfalsetwo will write first to the console. But this is not so. He doesn't write at all. This really works like that, and I wrote a three-dimensional expression as an if statement. It works from left to right, and it does not need to evaluate the rest of the code. All other statements are not available after the first false statement.

 private static int Proof2() { if (ternaryTrueOne()) { if (ternaryTrueTwo()) { if (ternaryFalseOne()) { if (ternaryTrueThree()) { if (ternaryFalseTwo()) { return 6; } else { return 7; } return 5; } else { return 6; } return 4; } else { return 5; } return 3; } else { return 4; } return 2; } else { return 3; } } 

Was there an incorrect original answer? What does correct associativity mean?

+5
source share
2 answers

Since the ternary conditional operator has its place in the operator priority table (i.e., no other operator has exactly the same priority as it), the associativity rule applies only when the conditional operator is ambiguous from another.

Right-to-left compatibility means that implicit parentheses are located around the rightmost triple.

I.e

a ? b : c ? d : e

equivalently

a ? b : (c ? d : e) a ? b : (c ? d : e) .

https://en.wikipedia.org/wiki/Operator_associativity - useful link.

+5
source

Associativity and execution order are related but not identical.

Associativity exists regardless of any execution - it is defined in mathematics, which consists exclusively of pure functions, so the "order of execution" does not affect the result.

The execution order in the ternary operator in C # is very simple:

  • Rate Condition
  • Evaluate trueBranch if the condition is true, or falseBranch if the condition is false.

You can imagine associativity rules as "where the partners belong."

Consider this:

 a ? b : c ? d : e 

If we donโ€™t know anything about how associativity works, we can see different ways of setting parameters:

  • (a? b: c)? d: e
  • a? b: (c? d: e)

The first approach is left associative, the second is right associative

It is easy to see that both approaches lead to different results. For instance,

 (true ? true : false) ? false : false // false true ? true : (false ? false : false) // true 

Now, if you rewrite this into separate if (this is usually not the way the Trojan actually executes, but it will do), you will get the following:

 if (a) { return b; } else { if (c) return d; else return e; } 

The rating is the same as with a simple triple:

  • Rate condition a
  • If true, evaluate and return b ; otherwise continue
  • Rate condition c
  • If true, evaluate and return d ; otherwise rate and return e

This should make it clear how associativity and execution order work. So, we can finish the trip and explain your example.

We have a number of nested conventions:

 a ? b ? c ? 0 : 1 : 2 : 3 

How is associativity applied here? This is not true. There is no associative operation here! What are you doing:

 a ? (b ? (c ? 0 : 1) : 2) : 3 

There is no other way to put parens - this is the only possible way to parse statements.

Since the ternary operator, well, the ternary, is a little difficult to understand, but it becomes more obvious when you rewrite it as a function (for example, a โ€œnon-built-in operatorโ€):

 var f = (a, b, c) => a ? b : c; f(a, f(b, f(c, 0, 1), 2), 3); 

There is no ambiguity - there is no alternative way to parse this expression.

The mapping of associativity with binary operators is a bit simpler, so consider this scenario:

 a - b - c 

If you don't know about associativity - , you can see two alternative ways to set parens - (a - b) - c and a - (b - c) , which can give you two different results. Thus, - not associative.

The comparison with + , which is ("completely") associative - (a + b) + c and a + (b + c) - is exactly the same thing.

+4
source

Source: https://habr.com/ru/post/1236903/


All Articles