{"id":863,"date":"2011-11-16T11:40:52","date_gmt":"2011-11-16T11:40:52","guid":{"rendered":"http:\/\/kera.name\/articles\/?p=863"},"modified":"2011-11-16T11:53:23","modified_gmt":"2011-11-16T11:53:23","slug":"ruby-does-equality-right-and-c-does-not","status":"publish","type":"post","link":"https:\/\/kera.name\/articles\/2011\/11\/ruby-does-equality-right-and-c-does-not\/","title":{"rendered":"Ruby Does Equality Right, And C++ Does Not"},"content":{"rendered":"<p>I was posed a question recently as to why the C++ expression <code>true == true == true<\/code> compiled successfully. The person asking was sure that equality comparison held no associativity and that the expression was thus too ambiguous to be well-formed.<\/p>\n<p>Well, in Ruby, <a href=\"http:\/\/romhack.wikia.com\/wiki\/Ruby_operators#Operator_associativity\">this <em>is<\/em> the case<\/a>:<\/p>\n<ul>\n<li>\n<p>Subtraction is left associative;<br \/>\nso <code>a - b - 3<\/code> acts like <code>(a - b) - 3<\/code>.<\/p>\n<\/li>\n<li>\n<p>Assignment is right associative;<br \/>\nso <code>a = b = 3<\/code> acts like <code>a = (b = 3)<\/code>.<\/p>\n<\/li>\n<li>\n<p>Equality is not associative;<br \/>\nso <code>a == b == 3<\/code> raises <code>SyntaxError<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>In fact, C++&#039;s equality operator is left associative, and my immediate thought was that Ruby&#039;s behaviour was a little odd.<\/p>\n<p>However, on further thought, I realised that it makes quite a bit of sense.<\/p>\n<p>For example, it essentially prevents the following mistake:<\/p>\n<pre><code>int x = 0, y = 0, z = 0;\nstd::cout << (x == y == z); \/\/ false<\/code><\/pre>\n<p>Naively, especially when coming directly from a mathematics background, one might expect the output of this program to be <code>true<\/code> because all three operands are equal.<\/p>\n<p>But in fact, C++'s comparison takes only two operands, and when implicit associativity is applied explicitly with parentheses, the program's true behaviour becomes more obvious:<\/p>\n<pre><code>int x = 0, y = 0, z = 0;\nstd::cout << ((x == y) == z);\n\/\/              true   == 0\n\/\/                 false<\/code><\/pre>\n<p>Ruby's position of completely disallowing such a form in its arithmetic expressions will prevent any such \"bugs\". Perhaps it would have been better had C++ adopted this position as well.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was posed a question recently as to why the C++ expression <code>true == true == true<\/code> compiled successfully. The person asking was sure that equality comparison held no associativity and that the expression was thus too ambiguous to be well-formed.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[21,20,62],"_links":{"self":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/863"}],"collection":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/comments?post=863"}],"version-history":[{"count":10,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/863\/revisions"}],"predecessor-version":[{"id":873,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/posts\/863\/revisions\/873"}],"wp:attachment":[{"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/media?parent=863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/categories?post=863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kera.name\/articles\/wp-json\/wp\/v2\/tags?post=863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}