Hacker News new | ask | show | jobs
by ronaldx 4444 days ago
The differences between programming syntax and elementary/Boolean algebra are very awkward to understand clearly and deal with correctly. We clearly understand mathematical algebra to work one way, and we naturally assume programming algebra works the same way, which it doesn't at all.

Here, the antagonist says that b can't be 1 and 2 at the same time, which would be self-evident in mathematical algebra, but turns out to be quite irrelevant to Javascript and to programming paradigms generally (since two statements will never be checked simultaneously).

This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel.

3 comments

>This difference in how syntax is understood actually presents a barrier to programming for modestly trained mathematicians, who would otherwise be expected to excel.

Although this is true in general that syntax can be a barrier to entry, the article provides a particularly poor example. If anything, the article demonstrates how mathematical training is good preparation for many pitfalls of programming.

Mathematicians are used to working with various equivalence relations, even in the same context. So if a modestly trained mathematician saw == and ===, she would immediately ask "what is the difference between these two ER's?".

And then when she finds out the essential difference is that you can override ==, it would be clear that all bets are off.

I can't imagine any mathematician taking more than a few minutes and a google search -- let alone 11 days -- to figure out this loophole.

> Mathematicians are used to working with various equivalence relations, even in the same context. So if a modestly trained mathematician saw == and ===, she would immediately ask "what is the difference between these two ER's?".

This perhaps illustrates my point. While you say == and === are equivalence relations (I would argue they are not), there is a wider problem.

= itself is an assignment operator and should never be considered as an equivalence relation. But it is normal to consider = as algebraic equality for anyone who has completed high school math.

It's a great loss to intuitive understanding that we use = for assignment. If anything, considering Javascript's == and === is a net benefit as programmers are more acutely aware of the issue here.

What percentage of time spent learning to program and recovering bugs is caused by overcoming this misintuition? It's surely a lot.

Wikipedia has further discussion: https://en.wikipedia.org/wiki/Assignment_%28computer_program...

> I can't imagine any mathematician taking more than a few minutes and a google search -- let alone 11 days -- to figure out this loophole.

If anything, mathematicians are incredibly used to overloaded equals operators.

> If anything, mathematicians are incredibly used to overloaded equals operators.

That's my point. The == sign meaning many things is unsurprising (and key to this "hack"), whereas explicitly using two different symbols for equivalence in the same expression is a huge, glaring signpost to pay attention.

As demonstrated in the postscript, it can still be accomplished when the symbols are all the same. So that difference is not the key to the hack. As ronaldx noted, the key is that a variable can change value in between two equivalence evaluations within a single statement.
Arguably the thing that tripped me up for the majority of the time was latching on to the fact that == and === are different, and trying to _always_ satisfy the two conditions, rather than just spotting that I can change the reference to b from within the first valueOf call. I'm not sure how much I'd read into the "if I was more of a mathematician and less of a dumb programmer this would have been solved trivially" argument.
If a == b iff a === b, then == ~ ===. If == and === are different (which they presumable are, because otherwise we would only use one symbol) then by definition there exist counter-examples of the thing you were trying to _always_ satisfy.

In other words, it would never even occur to a mathematician to make your mistake...

More to the point, a mathematician wouldn't assume that some arbitrary predicate that you are allowed to define at will behaves the same way as a system-defined equivalence operator.

Edit: Added last paragraph and readability changes. Also, ~ is another symbol for equality, this time equality over binary relations.

The postscript is irrelevant to the claim made in the original post on this thread. It's a conflated example and not indicative of real programming.

if "get" returns different values when called multiple times within a single expression, one of two things must be true: * Someone's overriding "get" with a mutation to the variable. In all but the very rarest of circumstances, that someone should be publicly shamed. It's a nice hack for the purpose of the article, but not real code. * there's some very fine-grained concurrency. This case is irrelevant to the OP's claim because concurrency of this sort is very likely a fundamental characteristic of the system at hand, and never an artifact of the language.

Which claim is that, exactly? And are you implying that the author's original solution is more indicative of real programming?

Both solutions work the same way - when accessing the value of "b" for the first check, b is mutated such that the next check will return a different value. Both of them are equally bad practices.

The == vs. === issue is the part that's actually irrelevant, it served as a red herring.

Umm , you missed a key point here. The first comparison is == while the second one is ===. These 2 are different. The == checks equivalent. Mathematically speaking he should have used === in both places.

These things are more of quirks of javascript than anything else. The post did nothing but made me hate javascript. Try doing the same in Java !

> Here, the antagonist says that b can't be 1 and 2 at the same time, which would be self-evident in mathematical algebra, but turns out to be quite irrelevant to Javascript and to programming paradigms generally (since two statements will never be checked simultaneously).

This isn't really a problem if b is enforced to be immutable.