Why is x == (x = y) not the same as (x = y) == x?











up vote
48
down vote

favorite
7












Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.





This question is different from order of evaluation of subexpressions in a Java expression in that x is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y), unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom



int oldX = x;
x = y;
return oldX == y;


which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.










share|improve this question




















  • 38




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    yesterday








  • 6




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    yesterday






  • 22




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    yesterday








  • 20




    The real question is why you want to write code like this.
    – Broman
    yesterday






  • 9




    The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
    – Eric Lippert
    15 hours ago

















up vote
48
down vote

favorite
7












Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.





This question is different from order of evaluation of subexpressions in a Java expression in that x is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y), unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom



int oldX = x;
x = y;
return oldX == y;


which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.










share|improve this question




















  • 38




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    yesterday








  • 6




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    yesterday






  • 22




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    yesterday








  • 20




    The real question is why you want to write code like this.
    – Broman
    yesterday






  • 9




    The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
    – Eric Lippert
    15 hours ago















up vote
48
down vote

favorite
7









up vote
48
down vote

favorite
7






7





Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.





This question is different from order of evaluation of subexpressions in a Java expression in that x is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y), unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom



int oldX = x;
x = y;
return oldX == y;


which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.










share|improve this question















Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.





This question is different from order of evaluation of subexpressions in a Java expression in that x is definitely not a 'subexpression' here. It needs to be loaded for the comparison rather than to be 'evaluated'. The question is Java-specific and the expression x == (x = y), unlike far-fetched impractical constructs commonly crafted for tricky interview questions, came from a real project. It was supposed to be a one-line replacement for the compare-and-replace idiom



int oldX = x;
x = y;
return oldX == y;


which, being even simpler than x86 CMPXCHG instruction, deserved a shorter expression in Java.







java variable-assignment operator-precedence jls






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 hours ago

























asked yesterday









John McClane

626314




626314








  • 38




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    yesterday








  • 6




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    yesterday






  • 22




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    yesterday








  • 20




    The real question is why you want to write code like this.
    – Broman
    yesterday






  • 9




    The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
    – Eric Lippert
    15 hours ago
















  • 38




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    yesterday








  • 6




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    yesterday






  • 22




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    yesterday








  • 20




    The real question is why you want to write code like this.
    – Broman
    yesterday






  • 9




    The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
    – Eric Lippert
    15 hours ago










38




38




The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
– Louis Wasserman
yesterday






The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
– Louis Wasserman
yesterday






6




6




Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
– Louis Wasserman
yesterday




Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
– Louis Wasserman
yesterday




22




22




Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
– jpmc26
yesterday






Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
– jpmc26
yesterday






20




20




The real question is why you want to write code like this.
– Broman
yesterday




The real question is why you want to write code like this.
– Broman
yesterday




9




9




The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
– Eric Lippert
15 hours ago






The key to your question is your false belief that parentheses imply evaluation order. That is a common belief because of how we're taught math in elementary school and because some beginner programming books still get it wrong, but it is a false belief. This is a pretty frequent question. You might benefit from reading my articles on the subject; they are about C# but they apply to Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
– Eric Lippert
15 hours ago














7 Answers
7






active

oldest

votes

















up vote
66
down vote













== is a binary equality operator.




The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







share|improve this answer



















  • 9




    The wording "appears to be" doesn't sound like they're sure, tbh.
    – Mr Lister
    19 hours ago








  • 28




    "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
    – Robyn
    18 hours ago






  • 7




    @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
    – Kelvin
    12 hours ago






  • 2




    in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
    – Michael Edenfield
    8 hours ago


















up vote
50
down vote













As LouisWasserman said, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



//the example values
x = 1;
y = 2;


So in quickReplaceAndCompare() the following is done:



x == (x = y)
1 == (x = y)
1 == (x = 2) //assign 2 to x, returns 2
1 == 2
false


and in badReplaceAndCompare():



(x = y) == x
(x = 2) == x //assign 2 to x, returns 2
2 == x
2 == 2
true


Note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






share|improve this answer























  • fyi, I edited out those functions from his question
    – pushkin
    10 hours ago


















up vote
12
down vote














which, by the order implied by brackets, should be calculated first




No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.



(And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)



Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.



Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.



Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".






share|improve this answer

















  • 1




    I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
    – John P
    6 hours ago


















up vote
1
down vote













In the first test you're checking does 1 == 3.



In the second test your checking does 3 == 3.



(x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?






share|improve this answer




























    up vote
    1
    down vote













    It is related to operator precedence and how operators are getting evaluated.



    Parentheses '()' has higher precedence and has associativity left to right.
    Equality '==' come next in this question and has associativity left to right.
    Assignment '=' come last and has associativity right to left.



    System use stack to evaluate expression. Expression gets evaluated left to right.



    Now comes to original question:



    int x = 1;
    int y = 3;
    System.out.println(x == (x = y)); // false


    First x(1) will be pushed to stack.
    then inner (x = y) will be evaluated and pushed to stack with value x(3).
    Now x(1) will be compared against x(3) so result is false.



    x = 1; // reset
    System.out.println((x = y) == x); // true


    Here,
    (x = y) will be evaluated, now x value become 3 and x(3) will be pushed to stack.
    Now x(3) with changed value after equality will be pushed to stack.
    Now expression will be evaluated and both will be same so result is true.






    share|improve this answer










    New contributor




    Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.














    • 2




      "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
      – Radiodef
      9 hours ago












    • @Radiodef, You are correct, updated my answer.
      – Amit
      1 hour ago




















    up vote
    0
    down vote













    It is not the same. The left hand side will always be evaluated before the right hand side, and the brackets don't specify an order of execution, but a grouping of commands.



    With:



          x == (x = y)




    You are basically doing the same as:



          x == y




    And x will have the value of y after the comparison.



    While with:



          (x = y) == x




    You are basically doing the same as:



          x == x



    After x took y's value. And it will always return true.






    share|improve this answer






























      up vote
      0
      down vote













      Basically the first statement x had it's value 1
      So Java compares 1 == to new x variable which won't be the same



      In the second one you said x=y which means the value of x changed and so when you call it again it'll be the same value hence why it's true and x ==x






      share|improve this answer








      New contributor




      Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.


















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53749841%2fwhy-is-x-x-y-not-the-same-as-x-y-x%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        7 Answers
        7






        active

        oldest

        votes








        7 Answers
        7






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        66
        down vote













        == is a binary equality operator.




        The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



        Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







        share|improve this answer



















        • 9




          The wording "appears to be" doesn't sound like they're sure, tbh.
          – Mr Lister
          19 hours ago








        • 28




          "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
          – Robyn
          18 hours ago






        • 7




          @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
          – Kelvin
          12 hours ago






        • 2




          in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
          – Michael Edenfield
          8 hours ago















        up vote
        66
        down vote













        == is a binary equality operator.




        The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



        Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







        share|improve this answer



















        • 9




          The wording "appears to be" doesn't sound like they're sure, tbh.
          – Mr Lister
          19 hours ago








        • 28




          "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
          – Robyn
          18 hours ago






        • 7




          @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
          – Kelvin
          12 hours ago






        • 2




          in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
          – Michael Edenfield
          8 hours ago













        up vote
        66
        down vote










        up vote
        66
        down vote









        == is a binary equality operator.




        The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



        Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







        share|improve this answer














        == is a binary equality operator.




        The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



        Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First








        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited yesterday

























        answered yesterday









        Andrew Tobilko

        24.5k84182




        24.5k84182








        • 9




          The wording "appears to be" doesn't sound like they're sure, tbh.
          – Mr Lister
          19 hours ago








        • 28




          "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
          – Robyn
          18 hours ago






        • 7




          @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
          – Kelvin
          12 hours ago






        • 2




          in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
          – Michael Edenfield
          8 hours ago














        • 9




          The wording "appears to be" doesn't sound like they're sure, tbh.
          – Mr Lister
          19 hours ago








        • 28




          "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
          – Robyn
          18 hours ago






        • 7




          @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
          – Kelvin
          12 hours ago






        • 2




          in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
          – Michael Edenfield
          8 hours ago








        9




        9




        The wording "appears to be" doesn't sound like they're sure, tbh.
        – Mr Lister
        19 hours ago






        The wording "appears to be" doesn't sound like they're sure, tbh.
        – Mr Lister
        19 hours ago






        28




        28




        "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
        – Robyn
        18 hours ago




        "appears to be" means the specification does not require that the operations are actually carried out in that order chronologically, but it requires that you get the same result that you would get if they were.
        – Robyn
        18 hours ago




        7




        7




        @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
        – Kelvin
        12 hours ago




        @MrLister "appears to be" appears to be a poor word choice on their part. By "appear" they mean "manifest as a phenomenon to the developer". "is effectively" may be a better phrase.
        – Kelvin
        12 hours ago




        2




        2




        in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
        – Michael Edenfield
        8 hours ago




        in the C++ community this is the equivalent to the "as-if" rule... the operand is required to behave "as if" it was implemented per the following rules, even if technically it is not.
        – Michael Edenfield
        8 hours ago












        up vote
        50
        down vote













        As LouisWasserman said, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



        //the example values
        x = 1;
        y = 2;


        So in quickReplaceAndCompare() the following is done:



        x == (x = y)
        1 == (x = y)
        1 == (x = 2) //assign 2 to x, returns 2
        1 == 2
        false


        and in badReplaceAndCompare():



        (x = y) == x
        (x = 2) == x //assign 2 to x, returns 2
        2 == x
        2 == 2
        true


        Note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






        share|improve this answer























        • fyi, I edited out those functions from his question
          – pushkin
          10 hours ago















        up vote
        50
        down vote













        As LouisWasserman said, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



        //the example values
        x = 1;
        y = 2;


        So in quickReplaceAndCompare() the following is done:



        x == (x = y)
        1 == (x = y)
        1 == (x = 2) //assign 2 to x, returns 2
        1 == 2
        false


        and in badReplaceAndCompare():



        (x = y) == x
        (x = 2) == x //assign 2 to x, returns 2
        2 == x
        2 == 2
        true


        Note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






        share|improve this answer























        • fyi, I edited out those functions from his question
          – pushkin
          10 hours ago













        up vote
        50
        down vote










        up vote
        50
        down vote









        As LouisWasserman said, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



        //the example values
        x = 1;
        y = 2;


        So in quickReplaceAndCompare() the following is done:



        x == (x = y)
        1 == (x = y)
        1 == (x = 2) //assign 2 to x, returns 2
        1 == 2
        false


        and in badReplaceAndCompare():



        (x = y) == x
        (x = 2) == x //assign 2 to x, returns 2
        2 == x
        2 == 2
        true


        Note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






        share|improve this answer














        As LouisWasserman said, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



        //the example values
        x = 1;
        y = 2;


        So in quickReplaceAndCompare() the following is done:



        x == (x = y)
        1 == (x = y)
        1 == (x = 2) //assign 2 to x, returns 2
        1 == 2
        false


        and in badReplaceAndCompare():



        (x = y) == x
        (x = 2) == x //assign 2 to x, returns 2
        2 == x
        2 == 2
        true


        Note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 14 hours ago









        Hulk

        2,49311635




        2,49311635










        answered yesterday









        Poohl

        493310




        493310












        • fyi, I edited out those functions from his question
          – pushkin
          10 hours ago


















        • fyi, I edited out those functions from his question
          – pushkin
          10 hours ago
















        fyi, I edited out those functions from his question
        – pushkin
        10 hours ago




        fyi, I edited out those functions from his question
        – pushkin
        10 hours ago










        up vote
        12
        down vote














        which, by the order implied by brackets, should be calculated first




        No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.



        (And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)



        Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.



        Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.



        Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".






        share|improve this answer

















        • 1




          I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
          – John P
          6 hours ago















        up vote
        12
        down vote














        which, by the order implied by brackets, should be calculated first




        No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.



        (And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)



        Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.



        Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.



        Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".






        share|improve this answer

















        • 1




          I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
          – John P
          6 hours ago













        up vote
        12
        down vote










        up vote
        12
        down vote










        which, by the order implied by brackets, should be calculated first




        No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.



        (And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)



        Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.



        Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.



        Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".






        share|improve this answer













        which, by the order implied by brackets, should be calculated first




        No. It is a common misconception that parentheses have any (general) effect on calculation or evaluation order. They only coerce the parts of your expression into a particular tree, binding the right operands to the right operations for the job.



        (And, if you don't use them, this information comes from the "precedence" and associativity of the operators, something that's a result of how the language's syntax tree is defined. In fact, this is still exactly how it works when you use parentheses, but we simplify and say that we're not relying on any precedence rules then.)



        Once that's done (i.e. once your code has been parsed into a program) those operands still need to be evaluated, and there are separate rules about how that is done: said rules (as Andrew has shown us) state that the LHS of each operation is evaluated first in Java.



        Note that this is not the case in all languages; for example, in C++, unless you're using a short-circuiting operator like && or ||, the evaluation order of operands is generally unspecified and you shouldn't rely on it either way.



        Teachers need to stop explaining operator precedence using misleading phrases like "this makes the addition happen first". Given an expression x * y + z the proper explanation would be "operator precedence makes the addition happen between x * y and z, rather than between y and z", with no mention of any "order".







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 18 hours ago









        Lightness Races in Orbit

        281k51453770




        281k51453770








        • 1




          I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
          – John P
          6 hours ago














        • 1




          I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
          – John P
          6 hours ago








        1




        1




        I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
        – John P
        6 hours ago




        I wish my teachers had made some separation between the underlying math and the syntax they used to represent it, like if we spent a day with Roman numerals or Polish notation or whatever and saw that addition has the same properties. We learned associativity and all those properties in middle school, so there was plenty of time.
        – John P
        6 hours ago










        up vote
        1
        down vote













        In the first test you're checking does 1 == 3.



        In the second test your checking does 3 == 3.



        (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



        In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?






        share|improve this answer

























          up vote
          1
          down vote













          In the first test you're checking does 1 == 3.



          In the second test your checking does 3 == 3.



          (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



          In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?






          share|improve this answer























            up vote
            1
            down vote










            up vote
            1
            down vote









            In the first test you're checking does 1 == 3.



            In the second test your checking does 3 == 3.



            (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



            In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?






            share|improve this answer












            In the first test you're checking does 1 == 3.



            In the second test your checking does 3 == 3.



            (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



            In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered yesterday









            Michael Puckett II

            3,71841436




            3,71841436






















                up vote
                1
                down vote













                It is related to operator precedence and how operators are getting evaluated.



                Parentheses '()' has higher precedence and has associativity left to right.
                Equality '==' come next in this question and has associativity left to right.
                Assignment '=' come last and has associativity right to left.



                System use stack to evaluate expression. Expression gets evaluated left to right.



                Now comes to original question:



                int x = 1;
                int y = 3;
                System.out.println(x == (x = y)); // false


                First x(1) will be pushed to stack.
                then inner (x = y) will be evaluated and pushed to stack with value x(3).
                Now x(1) will be compared against x(3) so result is false.



                x = 1; // reset
                System.out.println((x = y) == x); // true


                Here,
                (x = y) will be evaluated, now x value become 3 and x(3) will be pushed to stack.
                Now x(3) with changed value after equality will be pushed to stack.
                Now expression will be evaluated and both will be same so result is true.






                share|improve this answer










                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.














                • 2




                  "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                  – Radiodef
                  9 hours ago












                • @Radiodef, You are correct, updated my answer.
                  – Amit
                  1 hour ago

















                up vote
                1
                down vote













                It is related to operator precedence and how operators are getting evaluated.



                Parentheses '()' has higher precedence and has associativity left to right.
                Equality '==' come next in this question and has associativity left to right.
                Assignment '=' come last and has associativity right to left.



                System use stack to evaluate expression. Expression gets evaluated left to right.



                Now comes to original question:



                int x = 1;
                int y = 3;
                System.out.println(x == (x = y)); // false


                First x(1) will be pushed to stack.
                then inner (x = y) will be evaluated and pushed to stack with value x(3).
                Now x(1) will be compared against x(3) so result is false.



                x = 1; // reset
                System.out.println((x = y) == x); // true


                Here,
                (x = y) will be evaluated, now x value become 3 and x(3) will be pushed to stack.
                Now x(3) with changed value after equality will be pushed to stack.
                Now expression will be evaluated and both will be same so result is true.






                share|improve this answer










                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.














                • 2




                  "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                  – Radiodef
                  9 hours ago












                • @Radiodef, You are correct, updated my answer.
                  – Amit
                  1 hour ago















                up vote
                1
                down vote










                up vote
                1
                down vote









                It is related to operator precedence and how operators are getting evaluated.



                Parentheses '()' has higher precedence and has associativity left to right.
                Equality '==' come next in this question and has associativity left to right.
                Assignment '=' come last and has associativity right to left.



                System use stack to evaluate expression. Expression gets evaluated left to right.



                Now comes to original question:



                int x = 1;
                int y = 3;
                System.out.println(x == (x = y)); // false


                First x(1) will be pushed to stack.
                then inner (x = y) will be evaluated and pushed to stack with value x(3).
                Now x(1) will be compared against x(3) so result is false.



                x = 1; // reset
                System.out.println((x = y) == x); // true


                Here,
                (x = y) will be evaluated, now x value become 3 and x(3) will be pushed to stack.
                Now x(3) with changed value after equality will be pushed to stack.
                Now expression will be evaluated and both will be same so result is true.






                share|improve this answer










                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                It is related to operator precedence and how operators are getting evaluated.



                Parentheses '()' has higher precedence and has associativity left to right.
                Equality '==' come next in this question and has associativity left to right.
                Assignment '=' come last and has associativity right to left.



                System use stack to evaluate expression. Expression gets evaluated left to right.



                Now comes to original question:



                int x = 1;
                int y = 3;
                System.out.println(x == (x = y)); // false


                First x(1) will be pushed to stack.
                then inner (x = y) will be evaluated and pushed to stack with value x(3).
                Now x(1) will be compared against x(3) so result is false.



                x = 1; // reset
                System.out.println((x = y) == x); // true


                Here,
                (x = y) will be evaluated, now x value become 3 and x(3) will be pushed to stack.
                Now x(3) with changed value after equality will be pushed to stack.
                Now expression will be evaluated and both will be same so result is true.







                share|improve this answer










                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                share|improve this answer



                share|improve this answer








                edited 1 hour ago





















                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                answered 17 hours ago









                Amit

                4114




                4114




                New contributor




                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.





                New contributor





                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






                Amit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.








                • 2




                  "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                  – Radiodef
                  9 hours ago












                • @Radiodef, You are correct, updated my answer.
                  – Amit
                  1 hour ago
















                • 2




                  "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                  – Radiodef
                  9 hours ago












                • @Radiodef, You are correct, updated my answer.
                  – Amit
                  1 hour ago










                2




                2




                "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                – Radiodef
                9 hours ago






                "Assignment '=' come last and evaluated right to left." That's incorrect, or misleading. Assignments are right-to-left associative, which affects grouping in larger expressions, but their operands are evaluated left-to-right. Also see this answer and Precedence vs Associativity vs Order by Eric Lippert. Precedence isn't why x==(x=y) and (x=y)==x have different results.
                – Radiodef
                9 hours ago














                @Radiodef, You are correct, updated my answer.
                – Amit
                1 hour ago






                @Radiodef, You are correct, updated my answer.
                – Amit
                1 hour ago












                up vote
                0
                down vote













                It is not the same. The left hand side will always be evaluated before the right hand side, and the brackets don't specify an order of execution, but a grouping of commands.



                With:



                      x == (x = y)




                You are basically doing the same as:



                      x == y




                And x will have the value of y after the comparison.



                While with:



                      (x = y) == x




                You are basically doing the same as:



                      x == x



                After x took y's value. And it will always return true.






                share|improve this answer



























                  up vote
                  0
                  down vote













                  It is not the same. The left hand side will always be evaluated before the right hand side, and the brackets don't specify an order of execution, but a grouping of commands.



                  With:



                        x == (x = y)




                  You are basically doing the same as:



                        x == y




                  And x will have the value of y after the comparison.



                  While with:



                        (x = y) == x




                  You are basically doing the same as:



                        x == x



                  After x took y's value. And it will always return true.






                  share|improve this answer

























                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    It is not the same. The left hand side will always be evaluated before the right hand side, and the brackets don't specify an order of execution, but a grouping of commands.



                    With:



                          x == (x = y)




                    You are basically doing the same as:



                          x == y




                    And x will have the value of y after the comparison.



                    While with:



                          (x = y) == x




                    You are basically doing the same as:



                          x == x



                    After x took y's value. And it will always return true.






                    share|improve this answer














                    It is not the same. The left hand side will always be evaluated before the right hand side, and the brackets don't specify an order of execution, but a grouping of commands.



                    With:



                          x == (x = y)




                    You are basically doing the same as:



                          x == y




                    And x will have the value of y after the comparison.



                    While with:



                          (x = y) == x




                    You are basically doing the same as:



                          x == x



                    After x took y's value. And it will always return true.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 9 hours ago

























                    answered 9 hours ago









                    Or10n

                    134213




                    134213






















                        up vote
                        0
                        down vote













                        Basically the first statement x had it's value 1
                        So Java compares 1 == to new x variable which won't be the same



                        In the second one you said x=y which means the value of x changed and so when you call it again it'll be the same value hence why it's true and x ==x






                        share|improve this answer








                        New contributor




                        Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.






















                          up vote
                          0
                          down vote













                          Basically the first statement x had it's value 1
                          So Java compares 1 == to new x variable which won't be the same



                          In the second one you said x=y which means the value of x changed and so when you call it again it'll be the same value hence why it's true and x ==x






                          share|improve this answer








                          New contributor




                          Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.




















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            Basically the first statement x had it's value 1
                            So Java compares 1 == to new x variable which won't be the same



                            In the second one you said x=y which means the value of x changed and so when you call it again it'll be the same value hence why it's true and x ==x






                            share|improve this answer








                            New contributor




                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            Basically the first statement x had it's value 1
                            So Java compares 1 == to new x variable which won't be the same



                            In the second one you said x=y which means the value of x changed and so when you call it again it'll be the same value hence why it's true and x ==x







                            share|improve this answer








                            New contributor




                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            share|improve this answer



                            share|improve this answer






                            New contributor




                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            answered 4 hours ago









                            Ahmad Bedirxan

                            1




                            1




                            New contributor




                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.





                            New contributor





                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






                            Ahmad Bedirxan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53749841%2fwhy-is-x-x-y-not-the-same-as-x-y-x%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Plaza Victoria

                                Puebla de Zaragoza

                                Musa