Live data from Hacker News

JavaScript: The Curious Case of null >= 0

blog.campvanilla.com

141–150 of 152 posts

Re: JavaScript: The Curious Case of null >= 0

#141
post #123

Earlier quoted context omitted.

> Adding a third value would mean that a boolean variable binding could now have 5 values, true, false, not_true_or_false, null or undefined. That's nonsensical and deserves to be called out. FWIW, I actually agree with this. There's no need to add a new value. It would be fine with me (within the context of Javascript's already horribly broken design) to use an existing value (null or undefined) as the third "boolea…

It seems like this thread has gone several different directions. Surely suggesting that that (null>0) should return null or undefined is a separate topic from suggesting that if() statements have three different control branches? FWIW, I totally buy the former. If (null>0) returned null, then most things would still work as expected, and you could easily check the result of the comparison to catch unintended behavior…

The reason for the three-way IF would be to avoid conflating null and false. Without that you'd have to write:

    IF (x
That seems awkward to me.

Re: JavaScript: The Curious Case of null >= 0

#142
post #141

Earlier quoted context omitted.

It seems like this thread has gone several different directions. Surely suggesting that that (null>0) should return null or undefined is a separate topic from suggesting that if() statements have three different control branches? FWIW, I totally buy the former. If (null>0) returned null, then most things would still work as expected, and you could easily check the result of the comparison to catch unintended behavior…

The reason for the three-way IF would be to avoid conflating null and false. Without that you'd have to write: IF (x That seems awkward to me.

Yeah, I get that that's the intent, but (per my original comment) I'd think it would surely create more mess than it cleans up.

For example, I suspect that three-way IFs like you describe would only really get used in two ways - often the second and third branches would be identical, and the rest of the time the third branch will be some kind of "console.warn('bad inputs!')" kind of error handling.

For the latter of those two cases, testing for the error case before proceeding to the regular logic (as in your code sample above) seems intuitively like the right thing to do - analogously to how you might check (isNaN(operand)) before doing some math. And in the former case, if the second and third branches are identical you'd almost certainly want some syntactic sugar to avoid writing the same logic twice, like "IF (bool) {...} ELSE-AND-OTHERWISE {...}" -- which would just be isomorphic to what we have now. You know what I mean?

Re: JavaScript: The Curious Case of null >= 0

#143

Earlier quoted context omitted.

To be clear, I'm talking about strong/weak typing and static/dynamic typing as distinct concepts. My comment mostly applies to dynamic-typed languages. In JavaScript, `1 + {}` gives the string `1[object Object]`. In Python, `1 + {}` crashes. Neither language has a static type system, so neither language is able to disallow an expression like `a + b`; it needs to actually execute the code to find out that you're addin…

Why is crashing less often better in these cases? When it crashes, you know there is a problem with the code that needs to be fixed. When it doesn't, you might have nonsensical results that you're not aware of.

It depends on the exact context, but I think that in many cases, it's better to present wrong data to the user than to crash the page, since crashing the page makes it useless. Let's say Facebook accidentally introduces and ships some bug when computing the "like" count on about 1 in 5 news feed items. I could imagine two scenarios:

1.) The JS code crashes and the Facebook news feed page breaks for basically everyone. The flood of errors is reported to the error monitoring system and Facebook engineers frantically fix or roll back the problem to limit the amount of time Facebook is unusable.

2.) 1 in 5 news feed items shows "NaN people liked this", but Facebook is otherwise usable. The flood of errors is reported to the error monitoring system and Facebook engineers frantically fix or roll back the problem to limit the amount of time the weird "NaN people" message is shown.

Scenario #1 is a really bad outage, and scenario #2 is a temporary curiosity/annoyance that most people don't notice, and hopefully it's clear that scenario #2 is a better situation for everyone. But it really depends on context; if the bug is "a bank's website shows incorrect account balances", then crashing the page is probably a better user experience.

I'm certainly not saying JS got it right; JS doesn't do the part from #2 where it alerts you if there's a non-fatal error in production. But I think the basic idea of error resiliency has plenty of merit.

Re: JavaScript: The Curious Case of null >= 0

#144

The rule `if null = 0 is true` seems to rely upon the law of the excluded middle, which is violated by the comparison algorithms. I think this summarizes the issue.

More precisely, it relies on the assumption that

(x > y) || (x == y) || (x is true for all values x, y.

But the semantics of the comparison operators lead to null > 0 || null == 0 || null < 0 being false and the whole house of cards crumbles down.

Re: JavaScript: The Curious Case of null &gt;= 0

#145
post #122

Earlier quoted context omitted.

> Had his credentials been part of the first line, where he was confirming that he was serious about his previous post, then your interpretation would be correct. Wow, you have quite the exacting standards.

Hey...context matters. When you're talking about your own tendencies (whether you're likely to be serious or joking), who you are matters. When you're supporting your argument it doesn't. If you call that exacting standards, so be it. I call it reading comprehension.

> Hey...context matters

Indeed it does. So let's recall the context in which I made my original comment:

> Are you seriously suggesting that, widgety though JS's implicit type conversions might be, if its booleans had three values then things would be better?

That seemed to me to be a pretty non-constructive question, essentially a passive-aggressive way of saying, "You can't possibly be serious. You must be a complete newbie dweeb to come up with such a dumb idea."

That's why I responded the way I did.

Re: JavaScript: The Curious Case of null &gt;= 0

#146

Earlier quoted context omitted.

Humans not taking the time to understand SQL properly is their own fault though. Three value logic works perfectly well in the right hands. JavaScript is horrid :(

Re: "their own fault". In one sense, yes, that's true, but this type of reasoning irks me, because you're kind of assuming that the language design is inconsequential -- when it clearly isn't. I could also (somewhat absurdly) also argue that Malbolge[1] is a perfectly reasonable language. After all, if you fully understand Malbolge, it shouldn't be that difficult to write correct programs in it, right? This is obviou…

Well said. You should write a blog post or something on this topic.

Re: JavaScript: The Curious Case of null &gt;= 0

#147

Earlier quoted context omitted.

Indeed it does, and it's horribly error-prone because people don't actually understand it :/. It can also lead to quite convoluted query logic because you're giving up the "law of the excluded middle"[1] (amongst other things). For my money, the only sane thing to do with e.g. "null >= 0" is to throw an exception. (Even better would be just rejecting it at compile time, but JS obviously doesn't have that luxury.) [1]…

Humans not taking the time to understand SQL properly is their own fault though. Three value logic works perfectly well in the right hands. JavaScript is horrid :(

One thing that helps with three-value logic is to insist that all conditionals ultimately have to boil down to just true or false, even if they are using the third value in it. This is the case in C#, which implements three-value using nullable bools. So e.g. if you have this:

    bool? t = true;
    bool? f = false;
    bool? u = null; // "unknown"
Then you can do things like (t & u) or (f | u) or (!u), and it works as you'd expect. But you can't write:

    if (t & u) ...
for example, because "if" requires a definite true or false. So e.g. if you want it to execute only if your expression is definitely true, you do:

    if ((t & u) == true) ...
etc. Consequently, you don't get silent bugs because a null slips through somewhere - if your expression ends up introducing nulls at some point, you always have to decide what exactly it means for it to be null at the end of the pipeline.

Coincidentally, it also doesn't allow (t && u) or (f || u), for the same reason why it doesn't allow "if" - because the operators are short-circuited, and whether the second operand is evaluated or not has observable side effects, so null/unknown cannot be handled safely.

In SQL, on the other hand, the use of NULL is a conditional implicitly does what I did explicitly above - i.e. NULL is basically treated as FALSE - which IMO is wrong in principle, but more importantly, results in silent, hard to detect bugs.

Re: JavaScript: The Curious Case of null &gt;= 0

#148

Earlier quoted context omitted.

Non-zero does not imply `1'. >The pattern is basically directly lifted from C, where there's thankfully no such thing as a boolean type. There has been a boolean type in the current standard for C for longer than some of the younger people here have been alive.

Wow, I would never have known about stdbool. I have never seen it used (explicitly), even though it's been around since I was two years old. Thanks for bringing this to light! :- ) Nonetheless, bool or _Bool (aside from having implicit saturating arithmetic and assignment) is a one-bit integer type. It seems it mostly just formalizes the (implied, fictional) narrowing conversion involved in testing conditions, which…

That's because Boolean is a one-bit integer type. Whether you choose to call your 0s and 1s "false" and "true", correspondingly, doesn't change that.

Furthermore, from this perspective, a Boolean AND is just integer multiplication; Boolean OR is saturating addition; Boolean XOR is inequality; and Boolean IMP is saturating subtraction.

Re: JavaScript: The Curious Case of null &gt;= 0

#149
post #57

This being a result of JavaScript's weapons grade weak-typing, I've always wondered of what benefit weak typing actually brings, once dynamic typing is assumed, over strong typing as in python/Ruby. Or at least strong er typing. Reasonable coercion from 11434 -> "11434" is one thing, but why not throw an exception when anything more ambiguous is encountered? It would seem even for an absolute newcomer to programming,…

> I've always wondered of what benefit weak typing actually brings It makes your code crash less, and I would argue that in many cases that's desirable. I think it's a bit sad that the default behavior for computers is often to completely give up on the sight of any error. If you're running code in development or need to worry about data integrity, it makes sense to fail quickly and loudly, but if the analytics syste…

The problem with "avoid crashing at all costs" is that the alternative is usually "produce invalid output". The latter doesn't sound so bad in theory - but in practice, it means that the resulting bad data can go quite a long way, further accumulating errors as it flows through the pipeline. Worse yet if there are any observable actions taken on the basis of bad data (like, say deleting a file, or deciding to show some piece of private data).
Post reply on HN