Hacker News new | ask | show | jobs
by hashkb 3406 days ago
The real lesson is for language designers, who for some reason love using equals for assignment. Lisp got it right a hundred years ago and nobody learned.
4 comments

There is nothing wrong with using equals for assignment, the language designers just have to disallow assignments in if conditions.
It's a little weird. lvalues and rvalues are different things so a biased symbol feels nice to me, <-, e.g.
One more corner case, instead of designing orthogonal features.
It's not a corner case if you do it right.

For example, in C the assignment operator evaluates to the value of the right-hand side expression (so `int x = (y = 2);` initializes `x` to 2). But in Rust, the assignment operator always evaluates to `()` (a.k.a. "unit", the empty tuple), and trust me, this is how you want the language to work in the presence of pervasive move semantics and single ownership. Furthermore, nothing in Rust is "truthy": if-expressions accept a boolean and nothing else (this is also, IMO, exactly what you want in every language, but I'm sure others will disagree :P ). So `if x = 2 {` is a compiler error in Rust because `()` can't be coerced to a boolean (to say nothing of the fact that this reassignment would probably be a compiler error anyway because most variables in Rust are immutable). This doesn't require any acrobatics, it's just the natural fallout of how the rest of the language works.

Thanks, that's indeed a sensible way to do that.
That's a cure worse than the disease. If I faced a false choice between = as an assignment operator or else accepting syntax that distinguishes statements and expressions, I'd just take the = operator.
There's nothing wrong with using assignment in if conditions. For example, `if let Some(thing) = computation_that_may_fail { ... }`.
The operator there is let. The = is just a punctuator which indicates the initial value expression for the let.

Litmus test: if this was rendered into S-expressions, the let would stay, but the = would disappear.

No, that's just because the example I used was Rust. In Ruby it would be `if user = User.find(..)` and the same goes for Go and plenty of other languages.
If user is being freshly bound, that isn't an assignment but an initialization.

If the construct is not allowed when user is already in scope, it reflects the designer's view that an assignment in a conditional isn't a good thing.

If the construct is allowed when user exists already, with no diagnostic, then it carries the pitfalls that this thread is about.

Hacker News is implemented in a dialect of Lisp designed by a guy who wrote multiple books on Lisp. Seems even lispers don't learn:

> The assignment operator is =. I was dubious about this, but decided to try it and see if I got used to it. It turns out to work well, even in prefix. Stripes stand out, which is why they get used on warning signs and poisonous animals.

http://www.paulgraham.com/arcll1.html

That is quite silly. I briefly contemplated this idea for TXR Lisp, but completely rejected it. The = function is numeric comparison, like in Common Lisp. You don't want to turn that into assignment. People used to Lisp dialects where = is numeric comparison will make the mistake:

  (if (= whatever whatever-else) (you-got-burned))
Arc code written by people used to Lisp dialects where = is a pure comparison function, or Arc code converted from other Lisp dialects, has to be carefully reviewed against this.

If I put this into a Lisp dialect, I would make the code walker issue a warning whenever the value of a (= ...) assignment is used, and provide an alternative assignment operator which doesn't have that warning.

I'd say the issue is keyboard designers, if ':' didn't require shift I bet we'd see it for assignment more often.
Well, languages can either use another assignment operator or have type system that wont check that kind of statement. Both ways fix it.

In fact, it's not easy to have this kind of bug on your language. C just has it because people wanted to write stuff like `int a = b = 0`.

`int a <- b <- 0` or `int a := b := 0` would have worked just as well.

Programmers using equals for assignment is a bit of a misunderstanding of what the mathematical idiom "let x = 5" means. The assignment is signaled by "let", not by "=". In fact, several programming languages use "let" exactly for this purpose too.