Assignment Vs Equality Operator

Different ProgrammingLanguages have made different choices for representing assignment versus the EqualityOperator:

Assignment = and equality ==

This is the combination that leads to the most actual bugs, since (a = b) is a valid conditional expression in many of these languages. Is that the fault of the choice of lexemes (= and == as opposed to := or <- or something else), or the fact that assignments are valid expressions? Or are the "most actual bugs" due to the fact that the above languages account for the lion's share of production code being written these days?

Both. Java rarely has this problem, because foo = bar is not a boolean unless foo and bar are booleans, and hence can't be used in the predicate of a conditional. And Dylan went with := and == precisely so that a missing character couldn't change the meaning of the expression, even though its typechecker would catch most conditional bugs like this.

Additionally, most compilers these days will issue a warning for if (a = b) statements, and require an explicit comparison to remove that warning. I don't remember the last time an if (a = b) bug went unnoticed for any length of time in projects I've worked on. -- MikeWeller

Python also uses = to denote keyword arguments, which can bite when you intend to pass in a boolean.

Assignment := and equality =

Assignment := and equality == Assignment : and equality = No assignment, equality = No assignment, equality ==
    main :: IO ()
    main = --> There's an assignment
       let a = readLine() --> There's another one.
       in do f <- a       -- Binding.
             g <- a
             printLine f ++ g
assignment = and equality .EQ. Neither assignment nor equality is an infix operator Assignment and equality are both =, determined by context Assignment = and value equality == and value and type equality ("exactly equals") === Assignment =, equality ==, strict equality =:= Being a SingleAssignmentLanguage makes most unintentional assignments illegal. I find =:= awkward to type with having to press and release the shift key in the middle, but apparently Swedish keyboards are not laid out that way.

Assignment -> and value equality = and value and type equality ==

The assignment goes left-to-right in Pop-11 (e.g. x + 1 -> x), which I always rather liked.

Assignment <- and equality ==

Left-to-right assignment with "->" also works. "=" inside an 'if' or 'while' is a syntax error, "=" in a function call denotes keyword arguments, similar to Python, with the same pitfall. Unfortunately, more recent versions bow to widespread poor taste and also accept = as assignment outside of function arguments.


And to really blow one's mind is the triple equality (===) threesome. This checks to see if two variables share the same memory address (reference the same object). Personally, I think some kind of "sameAddr(v1,v2)" function should be included in a language instead of triple equals. They are too easy to confuse with double equals. Symbolic operations should be reserved for frequently-used operations. Use functions or library calls for the more obscure stuff.


Some languages also have different operators to mean "equal-valued" objects and "exact-same" object.

PythonLanguage handles this elegantly. Object equality is compared with '==' and object identity is compared with 'is'.

VisualBasic compares object equality with '=', and compares object identity with 'Is'. This causes the same sorts of confusion (especially when checking for nulls) as in SQL.

Although SQL does not have the concept of "exact-same" object, it does compare cell value equality with '=', and checks whether a cell is null with 'IS NULL'. This leads to some of the SqlFlaws.


I hear that some ExBase derivatives use = as an assignment for all types, = and == as equality for non-character types, == for string equality and = for prefix match on strings.


Ruby uses === for "case equality". It is used by the case..when (switch-like) construct. It is more permissive, so that you can match a string with a regexp, an instance with its type, a number with a range, or whatever is handy.


CoffeeScript uses = for assignment and the keywords is and isnt for equality.

        foo = 'bar'
        explode() if foo isnt 'bar'


See also: ComparingDynamicVariables


NovemberZeroFive

CategoryPitfall, CategoryConditionalsAndDispatching


EditText of this page (last edited January 4, 2014) or FindPage with title or text search