Somewhat unrelated: Can someone explain the rationale for writing comparisons in the ordering they're using (e.g., 2180 < week)?
I've seen similar before and always thought it seemed error-prone to not write them the way they'd be spoken aloud, but happy to entertain other explanations.
This is probably just me, but I always tend to write a bigger number in the right, so that I can picture a number line in my head.
(Which means I rarely use > and >= operators. It's always < or <=.)
Now, come to think about it, this might have something to do with my native language (Japanese). In Japanese, where the verb always comes at the end of a sentence, you can say "a < b" and "b > a" using the same order and same adjective.
a < b ... a -than b -toward bigger (a よりも b のほうが 大きい)
b > a ... b -toward a -than bigger (b のほうが a よりも 大きい)
I've seen style guides recommend that to avoid typos on == that accidentally result in assignment: write "123 == foo" instead of "foo == 123" so that you can't accidentally write "foo = 123".
It's not only about not accidentally writing `if (x=0)`.
The `if (0==x)` style also makes it obvious that the check is correct when reviewing/reading code. Sure, a linter might catch this. But this way the reader doesn't need to rely on that. Besides many codebases allow variable assignment as part of conditional/loop expressions, and sometimes sadly it's easier to write code this way than to get a team to use a linter.
Regarding it being unnatural... you get used to it, and especially in C one needs to take care to check the return code the right way (0!=, 0==, -1!=, 0<, !, etc.), whereas the other side of the check is often more straightforward (a function call, a variable etc.), so it's nice to have the constant up front. It takes very little extra space at the front. As a bonus all the constants will visually line up nicely that way.
> Surely such code would be caught by some other tool
This technique was invented back in the 1980s, back then compilers have no static analysis capabilities that we take for granted today. I think the reason of keep using it in 2020 is a matter of habit.
When working with lots of timeseries information I've found it helpful to always order comparisons so that left-to-right is always increasing, so I would write 2180 < week, or even (not 2180 < week) for the negation of the condition. This becomes almost required when there are multiple values being tested: (a <= 10 && 10 <= b && b <= c) is much easier to read than (a <= 10 && b >= 10 && b <= c). As a perspective, it's more focussed on establishing an invariant of the resulting data than writing a single predicate.
I assume it's a habit formed from guarding against unintentional assignment.
Less so for most comparisons, but for equality, it'll throw an error if you're using the wrong operator instead of having unintended side effects.
week = 2180 will set the week to 2180 in a lot of languages.
2180 = week will always throw an error.
So if I want to compare, it's safer to use the form of 2180 == week because if I forget the second '=', the compiler will tell me before I make bigger problems.
This mistake also requires that the assignment operator has a result (and further, that the result can be silently coerced into a boolean for whatever reason)
In both Rust and Swift, this mistake doesn't compile, their assignment operators don't have a result and so it can't very well be true (or false) ‡
‡ Technically the result of Rust's assignment operators is the empty tuple, which is the closest to "doesn't have a result" in the type system. I don't know about Swift.
Even more unrelated, but equally pedantic, I've always thought it's weird when people write "null != val" instead of "val != null" for the same reason.
When said out loud, "null is not val" just feels wrong.
I find initializing condtions like `if(Type variable = ...)` to be very nice in C++ to avoid excessive nesting while still keeping the variable scoped to the block. Of course, I also enable -Wparentheses for things like `if(val=null)`, which you get e.g. when using -Wall with both GCC and Clang.
In both these cases, this is caused by the language having built-in binary operators for when the left-hand side expression is a collection type that perform the operation elementwise and return an array.
Interestingly, it seems like PowerShell's operator overload resolution in general depends entirely on the type of the LHS. I say 'seems' because I couldn't find any sort of language specification when I looked into it a while ago like what C# and VB.NET have, and testing seemed to confirm that this was the case. Now, searching the PowerShell Core source, it seems from [1] that this is indeed the implementation.
This contrasts with C# [2] and VB.NET [3], where binary operator overload resolution is treated as if the candidate operator implementations were a two-parameter method group, making the resolution process 'commutative' (though not always commutative in practice as the operators themselves can still have different LHS and RHS types {Edit: example from the CLR [4]: +(Point, Size) but not +(Size, Point)}).
> it seemed error-prone to not write them the way they'd be spoken aloud
It is written the way it'd be spoken aloud. If you're not speaking it that way then you need to change the way you think. Programming is another language after all.
> I don't know about you, but "week is greater than 2180" sounds more natural than "2180 is less than week"
To you perhaps. To me, I think "if I put both sides on the number line, which way is being questioned? and is that question answered true or false?"
And therefore I almost always do an equals or less-than comparison because that's how I think about the number line: 0 in the center with negatives on the left and positives on the right.
So `if (week < 2048)` is just as valid and easy to think about as `if (!(2048 <= week))`. But then `if (!(2048 <= week))` provides an additional guarantee: that I won't accidentally assign to `week`.
I've seen similar before and always thought it seemed error-prone to not write them the way they'd be spoken aloud, but happy to entertain other explanations.