<p>C/C++ use <code>=</code> for assignment and <code>==</code> for equality comparision. For example, a snippet in C++ can be like this:</p>
<pre class="lang-cpp prettyprint-override"><code>int nuclear_code; 
nuclear_code = 1111; // assign nuclear_code  with the value 1111

if(nuclear_code == 1234) 
/* compare nuclear_code with the value 1234
** This will return false because 1111 != 1234
*/
{
    // This will never be executed.
    std::cout &lt;&lt; &quot;Nuclear fired!&quot;; 
}
</code></pre>
<p>But this can lead to unwanted bugs when programmers accidentally make a typo. Consider this example:</p>
<pre class="lang-cpp prettyprint-override"><code>int nuclear_code = 1111; 
if(nuclear_code = 1234) 
/* Oops, instead of ==, this is = now!
** This will assign nuclear_code with the value 1234
** and it will return the lvalue referring to the left-hand operand, which is 1234
** This is now true.
*/
{
    // This code will be run.
    std::cout &lt;&lt; &quot;Nuclear fired!&quot;; 
}
</code></pre>
<p>This is a (very) common typo in C/C++, partly because the two operators are so similar.</p>
<p>So what are the alternatives?</p>

<syntax><language-design>
What alternatives are there for C/C++ assignment operator (=) and equality operators (==) syntax?
CC BY-SA 4.0
2023-05-21T10:27:43.777Z
Whatever syntax you choose for these, you can prevent this exact mistake by not having assignment expressions at all. `nuclear_code = 1234;` can be a statement without `nuclear_code = 1234` needing to be allowed as an expression; Python did this before eventually relenting and adding the assignment operator `:=`. Another issue that works against C in this regard is the coercion to boolean; in Java, `if(nuclear_code = 1234)` would be a type error because the condition must be a `boolean`, not an `int`.
kaya3
CC BY-SA 4.0
2023-05-21T10:48:00.160Z
@kaya3 while that is true, the C/C++ way of doing it is a separate question in itself. I think that this still need to be asked.
justANewbie
CC BY-SA 4.0
2023-05-21T12:02:10.720Z
Yes, nothing wrong with the question. Just pointing out that there are more approaches to addressing this issue than just the choice of syntax for the two operators ─ and indeed, some languages use the same syntax `=` for both things because the context determines whether it's a name binding or an equality check.
kaya3
CC BY-SA 4.0
2023-05-21T19:03:19.813Z
so are you asking particularly about design strategies to prevent these kinds of mistakes? Because I don't see that represented in your title, and if you are (asking about that), it should be (represented in your title)
starball
CC BY-SA 4.0
2023-05-21T21:36:12.650Z
Not syntax, but in Swift assignment expressions are of type void, so this error can't happen either.
chrysante
CC BY-SA 4.0
2023-05-22T07:25:46.237Z
I think the point made by @chrysante deserves more attention. This works only because C++ allows you to put numeric expressions in `if()` statements. Disabling implicit conversiont from numbers to booleans would solve this issue. However, C++ also has implicit and explicit `operator bool`s. In some cases, this would still be a problem since, by convention, C++'s assignment returns a reference to the left hand side operand in order to enable assignment chaining (`a = b = c = d`).
Fureeish
<h3>Distinguish Assignment and Equality by Context</h3>
<p>Some languages use <code>=</code> for both assignment and equality. The way the language differentiates the two use cases is by constraining the grammar so it's obvious which context is meant.</p>
<p>For instance, in BASIC, there is no such thing as an &quot;expression statement&quot;, so if you write something like <code>x=1</code> on a line by itself, the only possible interpretation is that you are assigning 1 to <code>x</code>. The alternative interpretation of &quot;check if x is equal to 1 and discard the result&quot; isn't an allowed interpretation in the language. This is in contrast to a language like C where both interpretations are legal (and thus, the compiler needs an additional symbol to disambiguate the two interpretations). Some languages also use a keyword like <code>let</code> or <code>set</code> to begin an assignment statement which can also help distinguish the two.</p>
<p>The advantage of having only one operator for both operations is that it simplifies the language. It also means that the compiler will never misinterpret your program because of a careless error. On the other hand, it is less expressive than languages that separate out the two operations. For instance, in C++, you can assign to variables within a condition or loop. In a language like BASIC, you cannot do this which may lead to more verbose code in some cases.</p>

CC BY-SA 4.0
2023-05-21T12:30:57.220Z
2023-05-21T12:30:57.220Z
Isaiah
<h1>The Pascal way</h1>
<p>i.e using <code>:=</code> for assignment and <code>=</code> for equality check.</p>
<p>The example in the question can be written in Pascal as:</p>
<pre class="lang-pascal prettyprint-override"><code>program Hello;
var nuclear_code : integer;
begin
  nuclear_code := 1111;
  if(nuclear_code = 1234) then writeln('Nuclear fired!');
end.
</code></pre>
<p>This is so harder to mistype the two.</p>

CC BY-SA 4.0
2023-05-21T10:22:20.377Z
2023-05-21T10:22:20.377Z
justANewbie
CC BY-SA 4.0
2023-05-22T01:02:34.470Z
Just as a note about this, `:=` was chosen because it looked a bit like the left-arrow symbol in mathematics, ⟸, but wouldn't be confused for "less than or equal to". Prolog uses `:-` for a similar reason.
Pseudonym
CC BY-SA 4.0
2023-05-27T16:26:57.323Z
@Pseudonym I believe the `:=` symbol exists in mathematics as well, and has the meaning of introducing the definition for a new variable. The double arrows, on the other hand, I've never seen used for anything besides implication. Might be a case of poorly internationalized syntax, though)
abel1502
CC BY-SA 4.0
2023-07-10T18:47:58.090Z
That's what I am doing in [my programming language, AEC](https://flatassembler.github.io/AEC_specification.html#Operators).
FlatAssembler
CC BY-SA 4.0
2024-12-01T17:33:09.473Z
I think the Pascal way would have actually fit very nicely into C if `:=` were viewed as part of a general pattern of assignment operators being written as a symbol followed by an equals sign.  While `:` isn't exactly an operator, one could view the `:=` as though the left lvalue were preceded by `0?`, so `x := y;` would be equivalent to `x = 0 ? x : 5;`.
supercat
<p>Even though the OP sepcifically asks for different <em>syntax</em> to prevent this kind of error, I would make the case that a better approach is a <strong>semantic</strong> solution:</p>
<p>The reason why this error can occur in C++ (and in C for that matter) is that an assignment expression evaluates to a reference to the assigned variable (<code>int&amp;</code> in this case) and that <code>int</code> is implicitly convertible to <code>bool</code> (*). By changing either of these properties we can prevent this error.</p>
<hr />
<p>If we forbid implicit narrowing conversions or just the implicit <code>int -&gt; bool</code> conversion we are already fine. This however prevents the following common C idiom:</p>
<pre><code>int status = my_api_call(/* ... */);
if (status) { /* Handle error */ }
</code></pre>
<p>But I would argue that this alternative code is easier to understand and just as simple to write:</p>
<pre><code>int status = my_api_call(/* ... */);
if (status != 0) { /* Handle error */ }
</code></pre>
<hr />
<p>If we evaluate assignment expressions not to a reference to the assigned value but to <code>void</code> we also solve the problem, but this time we prevent this idiom:</p>
<pre><code>a = b = c; // Assign the value of c to a and b
</code></pre>
<p>However this is rarely used and confusing if not seen before, and the alternative</p>
<pre><code>a = c;
b = c;
</code></pre>
<p>is not significantly more verbose (and much clearer), so I would argue that losing this idiom is also not much of a loss if not an improvement.</p>
<hr />
<p>So in conclusion I argue that while either of the approaches solves the problem, both of them are reasonable in their on right and can prevent other possible code smells.</p>
<p>Also now you are free to choose whatever syntax you like without the restriction of having to solve this problem.</p>
<p>(*) On top of that, in clauses of <code>if</code> statements, also <em>explicit</em> conversions to <code>bool</code> are considered in C++. This rule exists so class authors can make conversions to <code>bool</code> explicit, which prevents implicit conversions from the custom type to integral types (via <code>class X</code> -&gt; <code>bool</code> -&gt; <code>int</code>) while still allowing the class to be used as a condition in <code>if</code> statements, but in our case it makes matters worse.</p>

CC BY-SA 4.0
2023-05-22T11:08:49.020Z
2023-05-23T16:59:04.983Z
2023-05-23T16:59:04.983Z
chrysante
CC BY-SA 4.0
2023-07-03T15:44:10.770Z
An alternative is only forbidding raw assignment in a boolean context. Extra-parentheses are cheap enough. Also, if `a`, `b` and/or `c` are long and/or expressions with side-effects, the rewrite will be quite cumbersome and not actually that trivial.
Deduplicator
CC BY-SA 4.0
2023-07-03T16:38:04.260Z
@Deduplicator If `a`, `b` or `c` are complex expressions, you can store them to temporaries. That's what the compiler does under the hood if you write a nested assignment expression anyhow. I agree that forbidding raw assignment in if-conditions is also a solution, but that does not prevent the error in other boolean expressions.
chrysante
<p>The <a href="https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wparentheses" rel="noreferrer">GNU solution</a> to the <code>if(x = y) {}</code> problem is to require double parenthesisation where only <code>if((x = y)) {}</code> is unambiguous.<br />
That said, to mean assignment, the <code>=</code>, <code>:=</code>, <code>&lt;-</code> and <code>←</code> operators are common across many languages descending from C, Pascal and BASIC.<br />
<a href="https://vale.dev/guide/introduction#variables" rel="noreferrer">Vale</a> uses a <code>set</code> keyword to mean reassignment.</p>
<p>In languages where the concept of &quot;(re)assignment&quot; does not exist, like most Functional and Logical ones, it is not uncommon to see <code>=</code> be used both for bindings and as the equality binary operator, along with <code>==</code>.<br />
For instance, in a language lacking builtin mutation support, this code is unambiguous:</p>
<pre><code>main =
    let x = 42 in
    putStrLn (if x = 42 then &quot;h&quot; else &quot;Ü&quot;)
</code></pre>
<p>Some English-oriented languages, like <a href="https://coffeescript.org/#operators" rel="noreferrer">CoffeeScript</a>, also use a <code>is</code> keyword.</p>
<p>For completeness, are also common as inequality operators <code>!=</code>, <code>/=</code>, <code>&lt;&gt;</code>, <code>≠</code> and <code>isnt</code>, all used in various languages.</p>

CC BY-SA 4.0
2023-05-22T02:07:55.873Z
2023-05-22T02:30:39.090Z
2023-05-22T02:30:39.090Z
Longinus
<h1>Just throw Unicode symbols at it (the APL way)</h1>
<p>APL uses <a href="https://aplwiki.com/wiki/Assignment" rel="noreferrer"><code>←</code></a> for assignment and <a href="https://aplwiki.com/wiki/Equal_to" rel="noreferrer"><code>=</code></a>/<a href="https://aplwiki.com/wiki/Match" rel="noreferrer"><code>≡</code></a> for equality (<code>=</code> is term-wise, <code>≡</code> is for the whole array). If you can afford to just throw Unicode at the problem, sometimes it's a fun solution :) really depends on how the language is meant to be written, though.</p>

CC BY-SA 4.0
2023-05-21T19:49:09.170Z
2023-05-21T19:49:09.170Z
RubenVerg
CC BY-SA 4.0
2023-05-22T01:52:30.177Z
Not just Unicode have those symbols. Some calculators' BASIC dialects use `←` as assignment too, from their limited character set.
Longinus
CC BY-SA 4.0
2023-05-22T04:16:19.187Z
Some dialects of Smalltalk use `_` for assignment, because early versions of ASCII had an arrow at that codepoint.
Bbrk24
CC BY-SA 4.0
2023-05-22T05:03:07.500Z
@Longinus sure, but nowadays SBCS's are basically just Unicode mappings.  I'd assume modern implementations of those BASIC's just read the (potentially sbcs-encoded) file and then display it as Unicode.
RubenVerg
CC BY-SA 4.0
2023-05-27T20:29:47.740Z
I can't really tell if this answer is serious. If it is, how do you expect users to type these symbols?
chrysante
CC BY-SA 4.0
2023-05-27T21:27:57.370Z
@chrysante It is completely serious. In Dyalog APL, you'd hit your APL key (backtick by default) and then `[`.
RubenVerg
CC BY-SA 4.0
2023-05-28T23:13:28.500Z
@chrysante On X.Org or Wayland systems, and others supporting XCompose or similar, `←` is [Multi, `<`, `-`].
Longinus
CC BY-SA 4.0
2023-05-29T05:33:52.183Z
@Longinus I've also seen [Multi, Left Arrow, Left Arrow]
RubenVerg
CC BY-SA 4.0
2023-07-03T22:36:00.513Z
@Longinus: TI calculators use expression `→` variable.
dan04
<p><strong>Common Lisp</strong></p>
<p>Most of the time when you need a variable, you'll use <code>let</code>.</p>
<pre class="lang-cl prettyprint-override"><code>(let ((x 10))
    ;; Now I can use x in this scope, and it has a value of 10
    ...)
</code></pre>
<p>There's also <code>setf</code>.</p>
<pre class="lang-cl prettyprint-override"><code>(setf *x* 10)
</code></pre>
<p>Equality checking looks like one of the following (depending on what exactly you want—there are more equality operators).</p>
<pre class="lang-cl prettyprint-override"><code>(= x 10)
(eql x 10)
(equalp x 10)
</code></pre>
<p>It's really hard to accidentally mix the two up.</p>

CC BY-SA 4.0
2023-05-23T18:15:57.437Z
2023-05-23T18:15:57.437Z
Aman Grewal
<h3>Use <code>&lt;-</code>.</h3>
<p>using <code>&lt;-</code> for assignment and <code>=</code> for equality check.</p>
<p>Like this:</p>
<pre class="lang-c prettyprint-override"><code>a &lt;- 5
b &lt;- 5

if a = b:
    . . .
</code></pre>
<p>PS: like APL, but not UNICODE.</p>

CC BY-SA 4.0
2023-05-28T12:21:41.203Z
2023-05-28T12:21:41.203Z
чистов_n
CC BY-SA 4.0
2023-07-02T12:11:55.923Z
Or go full R and also allow `->` for right assignment, e.g. `f() -> x`
Jack Aidley
CC BY-SA 4.0
2023-07-12T14:53:22.280Z
But is `if a <- 5` an assignment, or a lesser-than comparison between `a` and `-5`? I think this particular notation just moves the problem, not prevent it, unless you require spaces around binary operators.
G. Sliepen
CC BY-SA 4.0
2023-11-09T16:03:55.133Z
@G.Sliepen Tokenisation should take care of that, the same way `++x` in C is a prefix incrementation, and neither two unary plus operations, nor one nor two additions. (not saying it's ideal for reading code in all langs, but it works)
Longinus
<h2>Use <code>:</code>, like JSON</h2>
<p>Assignment and comparison have different purposes, return values, and allowed syntactic locations. Therefore, they should be represented with bigger differences than a single extra character.</p>
<p>The use of <code>:</code> for &quot;assignments&quot; is already fairly common and should be familiar to users:</p>
<ul>
<li>JSON/object notation: uses colon to bind a value to a key.</li>
<li>English: like this list, where a colon associates a value or comment with an entry.</li>
</ul>
<p>This gives you a one-character solution for assignment, leaves <code>=</code> free for equality, and should be immediately clear to readers.</p>

CC BY-SA 4.0
2023-07-07T10:53:04.210Z
2023-07-07T10:53:04.210Z
BoppreH
CC BY-SA 4.0
2023-10-11T21:51:10.807Z
`:` is used for assignment in K and Q.
Adám
<p>It partly depends on the semantics of variables and the semantics of equality.</p>
<p>Some languages distinguish between <a href="https://en.wikipedia.org/wiki/Extensionality" rel="nofollow noreferrer">intensional and extensional equality</a>. One example of this might be a set of integers represented as a binary search tree. Two sets are intensionally equal if the trees have the same structure, but extensionally equal if the numbers in the sets are the same.</p>
<p>Yet other languages have different notions of equality testing that depends on whether or not they will coerce types. Does <code>3 == 3.0</code> in a dynamically typed language? Sometimes you want that and sometimes you don't.</p>
<p>Other languages have object identity, which is different from equality.</p>
<p>This is a lot of symbols for equality testing that you might need to invent! <a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html" rel="nofollow noreferrer">Common Lisp has four of them.</a></p>
<p>Logic languages have only one symbol <code>=</code>, and it means <a href="https://en.wikipedia.org/wiki/Unification_(computer_science)" rel="nofollow noreferrer">unification</a>. Just looking at simple values like numbers for the moment, if you type <code>X = Y</code>, then it can mean several things:</p>
<ul>
<li>If <code>X</code> is a free variable but <code>Y</code> has a value already bound to it, this assigns that value to <code>X</code>.</li>
<li>Same thing if <code>Y</code> is free but <code>X</code> is bound; this is left-assignment.</li>
<li>If <code>X</code> and <code>Y</code> are both bound, then this is an equality test.</li>
<li>If <code>X</code> and <code>Y</code> are both free, then this aliases the two variables together. A subsequent binding of <code>X</code> will automagically also bind <code>Y</code>.</li>
</ul>
<p>In general, <code>X</code> and <code>Y</code> could be data structures with some bound and some unbound variables inside it, in which case the full unification algorithm is run.</p>

CC BY-SA 4.0
2023-05-22T01:16:36.493Z
2023-05-22T01:16:36.493Z
Pseudonym
<p>In Assembly (<code>mov</code>) or more basic languages there is a keyword for assignment, such as:</p>
<pre><code>set X to 10
</code></pre>
<p>I am personally not a fan of this because I prefer punctuation as operators, but this is an option that resolves ambiguity.</p>
<p>Or in Assembly:</p>
<pre><code>mov rdi rax
</code></pre>

CC BY-SA 4.0
2023-05-22T03:40:42.050Z
2023-05-22T04:03:45.697Z
2023-05-22T04:03:45.697Z
CPlus
<h2>Different Spellings</h2>
<p>Other common variations for assignment are <code>:=</code> and (so far unmentioned) <code>&lt;-</code>.  JavaScript is notorious for having many different comparison operators.</p>
<p>Vale has <a href="https://verdagon.dev/blog/on-removing-let-let-mut" rel="nofollow noreferrer">the interesting variation</a> that <code>x = 42</code> is only a variable declaration, and assignment must be written <code>set x = 42</code>.  I find, like the author, that I also write many more dclarations than assignments.</p>
<h2>Different Semantics</h2>
<p>A functional language, using static single assignments, or one using <a href="https://en.wikipedia.org/wiki/Substructural_type_system#Linear_type_systems" rel="nofollow noreferrer">linear types</a>, allows assignment only within bindings, which can be marked with <code>let</code>.  Alternatively, since newer languages tend to discourage mutability and assignments, you could mark assignments with <code>set</code>, or do both.  Since <code>is</code> is no longer than <code>==</code> and <code>be</code> or <code>to</code> no longer than <code>:=</code> or <code>&lt;-</code>, this could be valid syntax:</p>
<pre class="lang-none prettyprint-override"><code>let there be light
if there is light then
    set heavens to waters.above
    set seas to waters.below
</code></pre>

CC BY-SA 4.0
2023-07-10T06:15:11.093Z
2023-07-10T06:15:11.093Z
Davislor
<p><a href="/questions/tagged/smalltalk" class="post-tag" title="show questions tagged &#39;smalltalk&#39;" aria-label="show questions tagged &#39;smalltalk&#39;" rel="tag" aria-labelledby="tag-smalltalk-tooltip-container">smalltalk</a></p>
<p>The original Smalltalk uses <code>←</code> for assignment and <code>=</code> for equality. It also uses <code>↑</code> for return.</p>
<p>The original Smalltalk developed at Xerox used its own workstation developed at Xerox with its own CPU developed at Xerox and its own input devices (keyboard and mouse) developed at Xerox. Smalltalk was its own Operating System as well.</p>
<p>All this to say that it also had its own character set and character encoding.</p>
<p>When Smalltalk first was ported to other systems using the ASCII character encoding, it turned out that ASCII had the character <code>^</code> at the same code point where Smalltalk had <code>↑</code>, so all Smalltalk was rendered with <code>^</code> for return on machines that used ASCII. It still looks like an upwards arrow, so it still kind of works.</p>
<p>Assignment was not so lucky, though: where Smalltalk had <code>←</code>, ASCII has <code>_</code>, so all assignments in Smalltalk were rendered as <code>_</code> in ASCII. This was somewhat unsatisfactory, so it was decided to change the language specification use <code>:=</code> for assignment. However, some Smalltalks still accept <code>_</code> even today.</p>

CC BY-SA 4.0
2023-07-06T11:14:15.323Z
2023-07-06T11:14:15.323Z
Jörg W Mittag
CC BY-SA 4.0
2023-07-06T17:05:22.350Z
I mentioned this in a comment on another answer, but this is much more thorough (as is expected from the nature of comments).
Bbrk24
<h1>Use <code>,=</code> or <code>;=</code></h1>
<p>We could already understand <code>,=</code> as the <code>+=</code>-like version of <code>,</code> in C-style operators. And <code>;=</code> looks less confusing, if you already <a href="https://langdev.stackexchange.com/a/272/1149">merge <code>,</code> with <code>;</code></a>.</p>

CC BY-SA 4.0
2023-07-07T04:48:47.843Z
2023-07-07T04:48:47.843Z
user23013
<p>Coming relatively out of left field is Swift’s pattern-matching operator <code>~=</code>. It’s rarely written in source, instead the result of desugaring a <code>switch</code> or <code>if case</code> statement, but you could use it instead of <code>==</code> for regular equality comparison if you wanted to.</p>

CC BY-SA 4.0
2023-05-22T04:21:08.703Z
2023-05-22T04:21:08.703Z
Bbrk24
<p>Modern programming languages like Go use the &quot;=&quot;/&quot;:=&quot; for assignment and &quot;==&quot; for the comparison. It gives a compile time error if you mistype &quot;=&quot; instead of &quot;==&quot;.
Another suggestion would be to use constants when comparing, but that wouldn't solve your problem with mistyping in C++.</p>

CC BY-SA 4.0
2023-05-21T15:57:07.623Z
2023-05-21T15:57:07.623Z
user514
CC BY-SA 4.0
2023-05-21T16:03:03.967Z
Welcome to PLDI. How does your answer differ from justANewbie's answer?
Isaiah
CC BY-SA 4.0
2023-05-21T17:53:27.070Z
@Isaiah Pascal uses `=` for equality comparison, and Go uses `==` for equality comparison. The point is that Go allows `=` instead of `:=` for assignment when it's not in an expression. This is also the same as Python ─ `=` is assignment but not an expression, `:=` is an assignment expression, `==` is an equality comparison.
kaya3
CC BY-SA 4.0
2023-05-22T01:56:04.340Z
"Modern programming languages like F# use `=` for both bindings and equality." It's a bold move to make a blanket statement like "modern PLs do _x_" when they disagree with each other on how to do _x_.
Longinus
<p>Most compiler have the decency to give you a warning if you use the wrong operator, or if the compiler isn't sure. For example, with a good C compiler I expect that</p>
<pre><code>if (nuclear_code = 1234) ...
</code></pre>
<p>gives a warning. And if I really want to store 1234 and then examine whether it is zero, these compilers may allow</p>
<pre><code>if ((nuclear_code = 1234))
</code></pre>
<p>which tells the compiler &quot;be quiet, I know what I'm doing&quot;.</p>
<p>Newer languages don't allow integers to be used as boolean values. So the first example might not compile if the = operator doesn't yield a result, or it yields an integer result which cannot be used in an &quot;if&quot; statement. That's assuming that</p>
<pre><code>if (condition = false)
</code></pre>
<p>would be very rare.</p>
<p>You could use different pairs of tokens. := and =, or = and .eq. like FORTRAN did, or a leftarrow for assignment. The warning, and possible changed semantics, is the simplest solution. In the end, if the code you type is not the code you wanted, that's your problem.</p>

CC BY-SA 4.0
2023-07-10T13:57:11.693Z
2023-07-10T13:57:11.693Z
gnasher729
<h1>You can raise an error</h1>
<p>For example this code in Python is correct:</p>
<pre class="lang-python prettyprint-override"><code>a = 11

if a == 22:
    print(&quot;Something&quot;)
</code></pre>
<p>But this:</p>
<pre class="lang-python prettyprint-override"><code>a = 11

if a = 22:
    print(&quot;Something&quot;)
</code></pre>
<p>raise an error (no confusing bug like C++):</p>
<pre class="lang-none prettyprint-override"><code>  File &quot;somefile.py&quot;, line 3
    if a = 22:
       ^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
</code></pre>

CC BY-SA 4.0
2023-07-10T07:39:16.670Z
2023-07-10T07:39:16.670Z
чистов_n
# What alternatives are there for C/C++ assignment operator (=) and equality operators (==) syntax?
Posted by: username_0 on 2023-05-21
C/C++ use = for assignment and == for equality comparision. For example, a snippet in C++ can be like this:
int nuclear_code; 
nuclear_code = 1111; // assign nuclear_code  with the value 1111

if(nuclear_code == 1234) 
/* compare nuclear_code with the value 1234
** This will return false because 1111 != 1234
*/
{
    // This will never be executed.
    std::cout << "Nuclear fired!"; 
}

But this can lead to unwanted bugs when programmers accidentally make a typo. Consider this example:
int nuclear_code = 1111; 
if(nuclear_code = 1234) 
/* Oops, instead of ==, this is = now!
** This will assign nuclear_code with the value 1234
** and it will return the lvalue referring to the left-hand operand, which is 1234
** This is now true.
*/
{
    // This code will be run.
    std::cout << "Nuclear fired!"; 
}

This is a (very) common typo in C/C++, partly because the two operators are so similar.
So what are the alternatives?
**Tags:** syntax language-design
> **Comments:**
> **username_1**: Whatever syntax you choose for these, you can prevent this exact mistake by not having assignment expressions at all. `nuclear_code = 1234;` can be a statement without `nuclear_code = 1234` needing to be allowed as an expression; Python did this before eventually relenting and adding the assignment operator `:=`. Another issue that works against C in this regard is the coercion to boolean; in Java, `if(nuclear_code = 1234)` would be a type error because the condition must be a `boolean`, not an `int`.  
> **username_0**: @kaya3 while that is true, the C/C++ way of doing it is a separate question in itself. I think that this still need to be asked.  
> **username_1**: Yes, nothing wrong with the question. Just pointing out that there are more approaches to addressing this issue than just the choice of syntax for the two operators ─ and indeed, some languages use the same syntax `=` for both things because the context determines whether it's a name binding or an equality check.  
> **username_2**: so are you asking particularly about design strategies to prevent these kinds of mistakes? Because I don't see that represented in your title, and if you are (asking about that), it should be (represented in your title)  
> **username_3**: Not syntax, but in Swift assignment expressions are of type void, so this error can't happen either.  
> **username_4**: I think the point made by @chrysante deserves more attention. This works only because C++ allows you to put numeric expressions in `if()` statements. Disabling implicit conversiont from numbers to booleans would solve this issue. However, C++ also has implicit and explicit `operator bool`s. In some cases, this would still be a problem since, by convention, C++'s assignment returns a reference to the left hand side operand in order to enable assignment chaining (`a = b = c = d`).  
---
## 17 answers
### Answer by username_12 on 2023-05-21. Score: 17
# Just throw Unicode symbols at it (the APL way)

APL uses [`←`](https://aplwiki.com/wiki/Assignment) for assignment and [`=`](https://aplwiki.com/wiki/Equal_to)/[`≡`](https://aplwiki.com/wiki/Match) for equality (`=` is term-wise, `≡` is for the whole array). If you can afford to just throw Unicode at the problem, sometimes it's a fun solution :) really depends on how the language is meant to be written, though.
> **Comments:**
> **username_11** (2023-05-22): Not just Unicode have those symbols. Some calculators' BASIC dialects use `←` as assignment too, from their limited character set.  
> **username_13** (2023-05-22): Some dialects of Smalltalk use `_` for assignment, because early versions of ASCII had an arrow at that codepoint.  
> **username_12** (2023-05-22): @Longinus sure, but nowadays SBCS's are basically just Unicode mappings.  I'd assume modern implementations of those BASIC's just read the (potentially sbcs-encoded) file and then display it as Unicode.  
> **username_3** (2023-05-27): I can't really tell if this answer is serious. If it is, how do you expect users to type these symbols?  
> **username_12** (2023-05-27): @chrysante It is completely serious. In Dyalog APL, you'd hit your APL key (backtick by default) and then `[`.  
> **username_11** (2023-05-28): @chrysante On X.Org or Wayland systems, and others supporting XCompose or similar, `←` is [Multi, `<`, `-`].  
> **username_12** (2023-05-29): @Longinus I've also seen [Multi, Left Arrow, Left Arrow]  
> **username_14** (2023-07-03): @Longinus: TI calculators use expression `→` variable.  
---
### Answer by username_5 on 2023-05-21. Score: 13
### Distinguish Assignment and Equality by Context

Some languages use `=` for both assignment and equality. The way the language differentiates the two use cases is by constraining the grammar so it's obvious which context is meant.

For instance, in BASIC, there is no such thing as an "expression statement", so if you write something like `x=1` on a line by itself, the only possible interpretation is that you are assigning 1 to `x`. The alternative interpretation of "check if x is equal to 1 and discard the result" isn't an allowed interpretation in the language. This is in contrast to a language like C where both interpretations are legal (and thus, the compiler needs an additional symbol to disambiguate the two interpretations). Some languages also use a keyword like `let` or `set` to begin an assignment statement which can also help distinguish the two.

The advantage of having only one operator for both operations is that it simplifies the language. It also means that the compiler will never misinterpret your program because of a careless error. On the other hand, it is less expressive than languages that separate out the two operations. For instance, in C++, you can assign to variables within a condition or loop. In a language like BASIC, you cannot do this which may lead to more verbose code in some cases.
---
### Answer by username_0 on 2023-05-21. Score: 13
The Pascal way
i.e using := for assignment and = for equality check.
The example in the question can be written in Pascal as:
program Hello;
var nuclear_code : integer;
begin
  nuclear_code := 1111;
  if(nuclear_code = 1234) then writeln('Nuclear fired!');
end.

This is so harder to mistype the two.
> **Comments:**
> **username_6** (2023-05-22): Just as a note about this, `:=` was chosen because it looked a bit like the left-arrow symbol in mathematics, ⟸, but wouldn't be confused for "less than or equal to". Prolog uses `:-` for a similar reason.  
> **username_7** (2023-05-27): @Pseudonym I believe the `:=` symbol exists in mathematics as well, and has the meaning of introducing the definition for a new variable. The double arrows, on the other hand, I've never seen used for anything besides implication. Might be a case of poorly internationalized syntax, though)  
> **username_8** (2023-07-10): That's what I am doing in [my programming language, AEC](https://flatassembler.github.io/AEC_specification.html#Operators).  
> **username_9** (2024-12-01): I think the Pascal way would have actually fit very nicely into C if `:=` were viewed as part of a general pattern of assignment operators being written as a symbol followed by an equals sign.  While `:` isn't exactly an operator, one could view the `:=` as though the left lvalue were preceded by `0?`, so `x := y;` would be equivalent to `x = 0 ? x : 5;`.  
---
### Answer by username_3 on 2023-05-22. Score: 12
Even though the OP sepcifically asks for different syntax to prevent this kind of error, I would make the case that a better approach is a semantic solution:
The reason why this error can occur in C++ (and in C for that matter) is that an assignment expression evaluates to a reference to the assigned variable (int& in this case) and that int is implicitly convertible to bool (*). By changing either of these properties we can prevent this error.

If we forbid implicit narrowing conversions or just the implicit int -> bool conversion we are already fine. This however prevents the following common C idiom:
int status = my_api_call(/* ... */);
if (status) { /* Handle error */ }

But I would argue that this alternative code is easier to understand and just as simple to write:
int status = my_api_call(/* ... */);
if (status != 0) { /* Handle error */ }


If we evaluate assignment expressions not to a reference to the assigned value but to void we also solve the problem, but this time we prevent this idiom:
a = b = c; // Assign the value of c to a and b

However this is rarely used and confusing if not seen before, and the alternative
a = c;
b = c;

is not significantly more verbose (and much clearer), so I would argue that losing this idiom is also not much of a loss if not an improvement.

So in conclusion I argue that while either of the approaches solves the problem, both of them are reasonable in their on right and can prevent other possible code smells.
Also now you are free to choose whatever syntax you like without the restriction of having to solve this problem.
(*) On top of that, in clauses of if statements, also explicit conversions to bool are considered in C++. This rule exists so class authors can make conversions to bool explicit, which prevents implicit conversions from the custom type to integral types (via class X -> bool -> int) while still allowing the class to be used as a condition in if statements, but in our case it makes matters worse.
> **Comments:**
> **username_10** (2023-07-03): An alternative is only forbidding raw assignment in a boolean context. Extra-parentheses are cheap enough. Also, if `a`, `b` and/or `c` are long and/or expressions with side-effects, the rewrite will be quite cumbersome and not actually that trivial.  
> **username_3** (2023-07-03): @Deduplicator If `a`, `b` or `c` are complex expressions, you can store them to temporaries. That's what the compiler does under the hood if you write a nested assignment expression anyhow. I agree that forbidding raw assignment in if-conditions is also a solution, but that does not prevent the error in other boolean expressions.  
---
### Answer by username_11 on 2023-05-22. Score: 10
The GNU solution to the if(x = y) {} problem is to require double parenthesisation where only if((x = y)) {} is unambiguous.
That said, to mean assignment, the =, :=, <- and ← operators are common across many languages descending from C, Pascal and BASIC.
Vale uses a set keyword to mean reassignment.
In languages where the concept of "(re)assignment" does not exist, like most Functional and Logical ones, it is not uncommon to see = be used both for bindings and as the equality binary operator, along with ==.
For instance, in a language lacking builtin mutation support, this code is unambiguous:
main =
    let x = 42 in
    putStrLn (if x = 42 then "h" else "Ü")

Some English-oriented languages, like CoffeeScript, also use a is keyword.
For completeness, are also common as inequality operators !=, /=, <>, ≠ and isnt, all used in various languages.
---
### Answer by username_15 on 2023-05-23. Score: 7
Common Lisp
Most of the time when you need a variable, you'll use let.
(let ((x 10))
    ;; Now I can use x in this scope, and it has a value of 10
    ...)

There's also setf.
(setf *x* 10)

Equality checking looks like one of the following (depending on what exactly you want—there are more equality operators).
(= x 10)
(eql x 10)
(equalp x 10)

It's really hard to accidentally mix the two up.
---
### Answer by username_16 on 2023-05-28. Score: 7
Use <-.
using <- for assignment and = for equality check.
Like this:
a <- 5
b <- 5

if a = b:
    . . .

PS: like APL, but not UNICODE.
> **Comments:**
> **username_17** (2023-07-02): Or go full R and also allow `->` for right assignment, e.g. `f() -> x`  
> **username_18** (2023-07-12): But is `if a <- 5` an assignment, or a lesser-than comparison between `a` and `-5`? I think this particular notation just moves the problem, not prevent it, unless you require spaces around binary operators.  
> **username_11** (2023-11-09): @G.Sliepen Tokenisation should take care of that, the same way `++x` in C is a prefix incrementation, and neither two unary plus operations, nor one nor two additions. (not saying it's ideal for reading code in all langs, but it works)  
---
### Answer by username_19 on 2023-07-07. Score: 6
## Use `:`, like JSON

Assignment and comparison have different purposes, return values, and allowed syntactic locations. Therefore, they should be represented with bigger differences than a single extra character.

The use of `:` for "assignments" is already fairly common and should be familiar to users:

* JSON/object notation: uses colon to bind a value to a key.
* English: like this list, where a colon associates a value or comment with an entry.

This gives you a one-character solution for assignment, leaves `=` free for equality, and should be immediately clear to readers.
> **Comments:**
> **username_20** (2023-10-11): `:` is used for assignment in K and Q.  
---
### Answer by username_6 on 2023-05-22. Score: 4
It partly depends on the semantics of variables and the semantics of equality.

Some languages distinguish between [intensional and extensional equality](https://en.wikipedia.org/wiki/Extensionality). One example of this might be a set of integers represented as a binary search tree. Two sets are intensionally equal if the trees have the same structure, but extensionally equal if the numbers in the sets are the same.

Yet other languages have different notions of equality testing that depends on whether or not they will coerce types. Does `3 == 3.0` in a dynamically typed language? Sometimes you want that and sometimes you don't.

Other languages have object identity, which is different from equality.

This is a lot of symbols for equality testing that you might need to invent! [Common Lisp has four of them.](http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html)

Logic languages have only one symbol `=`, and it means [unification](https://en.wikipedia.org/wiki/Unification_(computer_science)). Just looking at simple values like numbers for the moment, if you type `X = Y`, then it can mean several things:

* If `X` is a free variable but `Y` has a value already bound to it, this assigns that value to `X`.
* Same thing if `Y` is free but `X` is bound; this is left-assignment.
* If `X` and `Y` are both bound, then this is an equality test.
* If `X` and `Y` are both free, then this aliases the two variables together. A subsequent binding of `X` will automagically also bind `Y`.

In general, `X` and `Y` could be data structures with some bound and some unbound variables inside it, in which case the full unification algorithm is run.
---
### Answer by username_21 on 2023-05-22. Score: 4
In Assembly (mov) or more basic languages there is a keyword for assignment, such as:
set X to 10

I am personally not a fan of this because I prefer punctuation as operators, but this is an option that resolves ambiguity.
Or in Assembly:
mov rdi rax
---
### Answer by username_22 on 2023-07-10. Score: 4
Different Spellings
Other common variations for assignment are := and (so far unmentioned) <-.  JavaScript is notorious for having many different comparison operators.
Vale has the interesting variation that x = 42 is only a variable declaration, and assignment must be written set x = 42.  I find, like the author, that I also write many more dclarations than assignments.
Different Semantics
A functional language, using static single assignments, or one using linear types, allows assignment only within bindings, which can be marked with let.  Alternatively, since newer languages tend to discourage mutability and assignments, you could mark assignments with set, or do both.  Since is is no longer than == and be or to no longer than := or <-, this could be valid syntax:
let there be light
if there is light then
    set heavens to waters.above
    set seas to waters.below
---
### Answer by username_23 on 2023-07-06. Score: 2
[smalltalk](/questions/tagged/smalltalk "show questions tagged 'smalltalk'")

The original Smalltalk uses `←` for assignment and `=` for equality. It also uses `↑` for return.

The original Smalltalk developed at Xerox used its own workstation developed at Xerox with its own CPU developed at Xerox and its own input devices (keyboard and mouse) developed at Xerox. Smalltalk was its own Operating System as well.

All this to say that it also had its own character set and character encoding.

When Smalltalk first was ported to other systems using the ASCII character encoding, it turned out that ASCII had the character `^` at the same code point where Smalltalk had `↑`, so all Smalltalk was rendered with `^` for return on machines that used ASCII. It still looks like an upwards arrow, so it still kind of works.

Assignment was not so lucky, though: where Smalltalk had `←`, ASCII has `_`, so all assignments in Smalltalk were rendered as `_` in ASCII. This was somewhat unsatisfactory, so it was decided to change the language specification use `:=` for assignment. However, some Smalltalks still accept `_` even today.
> **Comments:**
> **username_13** (2023-07-06): I mentioned this in a comment on another answer, but this is much more thorough (as is expected from the nature of comments).  
---
### Answer by username_24 on 2023-07-07. Score: 2
# Use `,=` or `;=`

We could already understand `,=` as the `+=`-like version of `,` in C-style operators. And `;=` looks less confusing, if you already [merge `,` with `;`](https://langdev.stackexchange.com/a/272/1149).
---
### Answer by username_13 on 2023-05-22. Score: 2
Coming relatively out of left field is Swift’s pattern-matching operator `~=`. It’s rarely written in source, instead the result of desugaring a `switch` or `if case` statement, but you could use it instead of `==` for regular equality comparison if you wanted to.
---
### Answer by username_25 on 2023-05-21. Score: 2
Modern programming languages like Go use the "="/":=" for assignment and "==" for the comparison. It gives a compile time error if you mistype "=" instead of "==".
Another suggestion would be to use constants when comparing, but that wouldn't solve your problem with mistyping in C++.
> **Comments:**
> **username_5** (2023-05-21): Welcome to PLDI. How does your answer differ from justANewbie's answer?  
> **username_1** (2023-05-21): @Isaiah Pascal uses `=` for equality comparison, and Go uses `==` for equality comparison. The point is that Go allows `=` instead of `:=` for assignment when it's not in an expression. This is also the same as Python ─ `=` is assignment but not an expression, `:=` is an assignment expression, `==` is an equality comparison.  
> **username_11** (2023-05-22): "Modern programming languages like F# use `=` for both bindings and equality." It's a bold move to make a blanket statement like "modern PLs do _x_" when they disagree with each other on how to do _x_.  
---
### Answer by username_26 on 2023-07-10. Score: 2
Most compiler have the decency to give you a warning if you use the wrong operator, or if the compiler isn't sure. For example, with a good C compiler I expect that
if (nuclear_code = 1234) ...

gives a warning. And if I really want to store 1234 and then examine whether it is zero, these compilers may allow
if ((nuclear_code = 1234))

which tells the compiler "be quiet, I know what I'm doing".
Newer languages don't allow integers to be used as boolean values. So the first example might not compile if the = operator doesn't yield a result, or it yields an integer result which cannot be used in an "if" statement. That's assuming that
if (condition = false)

would be very rare.
You could use different pairs of tokens. := and =, or = and .eq. like FORTRAN did, or a leftarrow for assignment. The warning, and possible changed semantics, is the simplest solution. In the end, if the code you type is not the code you wanted, that's your problem.
---
### Answer by username_16 on 2023-07-10. Score: 1
You can raise an error
For example this code in Python is correct:
a = 11

if a == 22:
    print("Something")

But this:
a = 11

if a = 22:
    print("Something")

raise an error (no confusing bug like C++):
  File "somefile.py", line 3
    if a = 22:
       ^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
---
