- Feature Articles
- CodeSOD
- Error'd
-
Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Edit Admin
Even the
arr?.length && shouldNotShowalone makes me cringe, and that's before I read the rest and see the more serious WTF.Sure,
arr?.lengthworks in JavaScript but anyone looking at it needs to stop and think about what's happening and you need to know JavaScript specific rules, like thatnullis false-ey as is0. I would consider((arr?.length) ?? 0) > 0instead, maybe more characters to parse, but it's very explicit.I also as a general practice avoid boolean variables that have a "negative" in their name as that also increases cognitive load when trying to parse expressions, especially if someone is trying to negate them, e.g. if
!shouldNotShowmaybe appeared elsewhere in the code. It could easily be renamed toshouldHideor if you inverting it isn't an issue,shouldShow.This article is a super illustrative example of code which is hard to read, anyone looking at it has to spend way too much time trying to parse what it's actually doing and then whether that actually makes sense is probably even harder.
It's always worth making code easier to read towards making it more obviously correct rather than being less obviously wrong.
Admin
My first idea is this used to be (arr?.length > 0), and they wanted to add (shouldNotShow === false), and they pasted it in the wrong place, and didn't notice because it worked. So they like to be very explicit (>0 is optional, ===false is optional), and slightly clumsy, but a bit light on the WTF side.
Admin
meh, it originally was
arr?.length > 0and someone copy-and-pasted&& shouldNotShow === falseand did not fail to miss the wrong place -- not!Shit happens, hardly a WTF
Edit Admin
Even the final code
!(arr?.length && shouldNotShow)suggests the original logic was either flawed or counterintuitive.Because Intuitively, you want to show the array if it's non-empty AND you're configured to do so, so you'd have something like
if(arr?.length && !shouldNotShow) { RenderArray(); }.Edit Admin
In what insane world does it make sense that the equivalence comparison operator
===has different and lower precedence than the greater-than comparison operator\>???
ISTM every operator that performs a comparison and returns a boolean result should have the same precedence. One can debate where AND and OR fit in there, but differing precedences for different comparisons? Truly wacky.
The real WTF is precedences like that. A total foot gun. Which the offshore idiot promptly used to shoot up the neighborhood.
Edit Admin
In the insane world of JavaScript, that's where. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence .
But it's also true of C (https://en.cppreference.com/w/c/language/operator_precedence.html) and C++ (https://en.cppreference.com/w/cpp/language/operator_precedence.html). And C# (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/). And Java (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html).
So I'd say that relationals being higher in precedence than equality is the norm, and treating them as strictly equal in precedence is a (relative) rarity. Well, that rarity does include APL, where all operators are of equal precedence (can be overridden by parentheses), and also right-to-left associative. (Yes, that means that in APL,
4 × 3 + 7is 40, and not 19, but3 x 4 + 7is 33, but7 + 3 x 4and7 + 4 × 3are both 19.)Addendum 2026-03-18 08:59: Just to be clear, the less/greater operators, including less-or-equal and greater-or-equal, are "relational" operators, while the equal/not-equal operators (
=====!=!==) are "equality" operators. Neither group is called "comparison operators".Edit Admin
In what insane world?
I don't know, but in every language I know. What makes perfect sense, because if the comparison would have the same or higher precedence, you would then do exactly what is happening here: Comparing a boolean result whether it's higher or lower.
Imagine x and y should be either both negative or both positive. You can write it like this:
x < 0 == y < 0
In which insane world should this not make sense?
Edit Admin
That's exactly my first thought as well.
Edit Admin
One of my rules when reviewing code is that only boolean values can be used in a boolean context. Things like
if arrayorif array.lengthare not allowed. If you mean "if the length of the array is greater than 0", you must writeif array.length > 0.Admin
Your intuition is correct, because the equivalent expression to
arr?.length && shouldNotShow === false > 0isarr?.length && !shouldNotShow.Can easily be tested in every browser (F12-Tools). Simplifying arr?.length and shouldNotShow to a boolean each leads to
false && false === false > 0=> false,false && !false=> false,!(false && false)=> truefalse && true === false > 0=> false,false && !true=> false,!(false && true)=> truetrue && true === false > 0=> false,true && !true=> false,!(true && true)=> falsetrue && false === false > 0=> true,true && !false=> true,!(true && false)=> falseEdit Admin
This is true in a number of languages, and I think many programmers find it intuitive. All the "empty-ish" values are falsey.
Edit Admin
x < 0 == y < 0 IMHO that should be an XOR operation not an equality
Edit Admin
If you have two booleans,
xoris an "equality" operator in the sense that not-equals is an "equality" operator because in languages that have a proper boolean type (as opposed to just coercing integers into the role)xoris not-equals. Anywayx < 0 == y < 0is not anxorsince you want both comparisons to be true or both comparisons to be false.Edit Admin
Strictly speaking, (mathematically) the comparison operators are relations and so are the equality operators. They are operators that describe relations between two objects. I'm not surprised that Javascript tramples over the normal nomenclature. A lot of languages do. OK equality is a comparison, perhaps we should describe the greater than and less than operators as ordering operators.
Anyway, it makes sense that equality is often given a lower precedence than greater than and less than because the result of all of these operators is of boolean type. Booleans don't have an ordering.
(a > 0) == (b > 0)makes sense but reversing the precedence:a > (0 == b) > 0is garbage and having equal precedence((a > 0) == b) > 0(assuming left associativity) is also garbage. It makes sense that the precedence is set up so that using no parentheses gives a sensible result.Admin
If I saw that in a PR I would flag it as needlessly confusing and insist on either parentheses or degolfing it. I don't care if it's fully specified and works, it's going to slow down every developer who reads that line in the future
Edit Admin
Not an XOR operation, but an XNOR (or perhaps NXOR, to be debated...) operation.
Admin
Adding parentheses takes about 10 seconds.