| > although I certainly can't miss the line where it happens. Consider the following for many C-style languages: if (a = b) { a = a + 1; };
If there is any goodness in the world, I'll never write/fix another of these bugs again. This is the only reason languages have an '==' operator.In many LISPs this type of bug is practically impossible to implement accidentally. (if (= a b) (incf a)) ; This form, by itself, can't assign b to a.
To recreate the bug as before, I would mangle the statement or have explicit declarations outside the conditional block. (if (progn (setf a b) (= a b)) (incf a))) ; uh, maybe? Does it even compile? I don't know how to computer.
(setf a b)
(if (= a b) (incf a)) ; more likely, but 'setf' would raise flags and the if statement itself isn't doing the mutating.
Clojure makes this even harder because of it's immutability by default. (let [a b] ; statement must enclose 'if' block, which would be a red flag.
(if (= a b) (inc a)) ; technically I can't 'change' anything here w/o the mutation primitives.
(if (let [a b] (= a b)) (inc a)) ; mutate in conditional, but the 'a' doesn't change outside the block,
; and now you have two bugs.
(if true (let [a b] (inc a))) ; Mimics the bug from the top, but the statement is mangled beyond comprehension.
|
Which leaves the distinction between assignment and comparison - which is always there - as the only reason to have two distinct operators. Which ones they are becomes a matter of taste, but as I recall, the reason why C settled on = for assignment is because it's that much more common. This is still the case today, even in pure languages where it's used for bindings only.