Hacker News new | past | comments | ask | show | jobs | submit login

> it said "= 0" rather than "== 0"

Why do so many programming languages have different equals/assigns operators?

There are languages that combine them and apparently don't have any problems. Is it something to do with being strongly vs. weakly typed?




The C designers wanted to be able to write stuff like `while ((ch = getchar()) != EOF) { ... }`, so assignment needed to be an expression. Secondly, C had no boolean type, and instead integers were used for boolean values (zero is false, nonzero is true). The combination of these two facts entails that an integer assignment is also a valid boolean expression.

To prevent accidental or malicious use of the assignment operator in place of the equals operator in a language, you either have to have a real boolean type, and no implicit conversion of other types to boolean, or make assignments not be an expression, or disallow assignment expressions in boolean contexts.

Making both operators the same symbol is not a good solution IMO, because it makes it harder to distinguish which is which in arbitrary contexts. E.g. in `a = b = c`, presumably the first is an assignment and the second a comparison? Or maybe not? It would just be confusing. Not sure which languages you are referring to that do this.


A common idiom to defang this was the "Yoda assignment":

  if (0 == do_something(foo)) { ... }
If one accidentally omits one equals-sign, it makes the compiler barf instead of becoming a silent-but-deadly kind of bug (whether intentional or not).

In Go, an assignment is not an expression, so the whole thing becomes illegal. I found this approach a bit offensive at first, but I got used to it rather quickly.


> or make assignments not be an expression,

Or just reverse the expression:

    0 == curent->uid
So that the bug case is an error:

    0 = current->uid


Yes, that is well known, but it doesn’t prevent the issue in TFA.


How does it not? Applied literally to the article, it would have turned this backdoor into a compile time error.


Because you can’t trust the person backdooring your code to help you out by writing in this style.


Yes, they could literally violate the coding style, but presumably, that would draw more attention to what they've done, not less.


I don’t think strong/weak typing is the culprit here.

I think partly that being explicit is nice. Assignment and equality are two very different things, so it makes sense for there to be different syntax. You can easily prevent the code in the article from working—just disallow assignment inside of expressions. This is probably a good idea, and a lot of newer languages make that choice.

Even when you read papers about programming, you often see different notation for assignment and equality. Assignment may be <- or := or something, and equality will just be =, to match the mathematical notation. I see a lot of <- in manuals for processors & architectures. I would hate to see something like this in my code base:

    a = x = y;
If that meant “set ‘a’ to true if ‘x’ is equal to ‘y’, and false otherwise.” I would, honestly, be a little pissed off.

I would only accept something like that if it meant (a==x)&&(x==y).


> I would hate to see something like this in my code base:

> a = x = y;

> If that meant “set ‘a’ to true if ‘x’ is equal to ‘y’, and false otherwise.” I would, honestly, be a little pissed off.

Would you find it more acceptable as `a = (x = y)`? To me, that is reasonably clear.


> Would you find it more acceptable as `a = (x = y)`? To me, that is reasonably clear.

No, I don’t consider that acceptable. It is not enough that it is clear to some people who know what they are looking at. The language should be more clear to more people.


It's just syntax. Pascal had := and =


Some to make them more distinct. Some because they treat assignment as an expression, and so either can occur in the same context.

In the former you could combine them. In the latter you can't (you need to be able to tell if "if (a = b) ..." contains a comparison or assignment).

(EDIT: I agree with the sibling reply from klodolph there - there are many cases where reusing the same operator would get really confusing, and so I'd prefer the operators to be distinct even if the language do not allow them in the same context)


It's been my impression over the years that = vs. == is one of the most common mistakes made in languages that use them. In which case, can it really be said to be less confusing?


There are two orthogonal issues here:

1) Do you allow assignment as an expression?

2) Do you use the same operator?

If you answer "yes" to #1, you must answer no to #2, but if you answer no to #1 you can choose whether or not you use the same operator. Consider these examples (assuming that if they're different, we use =/==, but of course any other set of operators could be substituted):

    # A) if 'yes' to 1 this would be a "double assignment", setting both a and b to c.
    a = b = c

    # B) if 'no' to 1, and 'yes' to 2, this would be an assignment of the comparison of b and c to a:
    a = b = c

    # C) if 'no' to 1 and 'no' to 2, this would be an assignment of the comparison of b and c to a:
    a = b == c

    # D) if 'no' to 1 and 'no' to 2, this would most likely be a syntax error:
    a = b = c
With respect to confusion, I'd argue that B) creates a lot of potential for confusion. You'd want "a = b = c" to either be "double assignment" (A) or a syntax error (D). If your language does not allow assignments as expressions, I'd go for C/D exactly for the reason you give, as the main reason not to allow assignments as expressions tends to be exactly to avoid the mistake you mention (it's trivial to support in a compiler/interpreter, so it's a question of whether you believe it's more helpful or more damaging)


Modern languages using that syntax tend to prevent that mistake by either outright disallowing assignments in boolean contexts, or by not having implicit conversion of other types to boolean, meaning that the mistake would be limited to the case of comparing a boolean variable to another value, which is quite rare. Some languages further limit the risk by making variables unmodifiable by default, meaning that it would have to be an explicitly modifiable boolean variable.

Assignment is one of the most frequent operations in typical programming languages, so it makes sense for it to be a single-character symbol, and ‘=’ is about the only fitting ASCII symbol for that. (With non-ASCII, there would be ‘≔’ or ‘←’ (the latter being used by APL), but those are non-obvious to type.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: