- 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
Admin
You omitted the last line of the article: "To be continued..."
Admin
I hope Annie also reverted the change to the CI job settings...
Admin
TRWTF is having to read code that says
if ("success" == data.status)
Admin
JavaScript is a language that was created to write bugs.
Admin
It should be standard practice to write unit tests for code. A couple of unit tests would have caught this error.
Admin
When I rule the world, removing error reporting on a linter will be a firing offence.
In fact, ignoring any compiler warnings will be a firing offence.
Firing squad offence.
Admin
It took me a while to get used to the "backwards" notation for == comparisons, but adopting the practice has saved me some headaches. I'd rather get used to odd notations than spend late hours chasing obscure bugs.
And perhaps, as Annie's organization matures, they will start requiring a team review of any CI or static analyzer config changes. Letting a lone developer make such a fundamental change is inviting disaster.
Admin
This bug can happen in lots of languages. Basically, all the languages whose syntax is derived from C.
Admin
The linter settings are a management control device. A dev unilaterally changing those is about like finding the dev rifling the boss'es desk during lunch break. Fire immediately upon discovery. Pour encourager les autres.
Admin
There are legitimate uses for an assignment expression as a condition in C-derived languages, including JavaScript. This of course is not one of them.
Practical example: You want to run a RegExp on a string and do something with the match information if there is one. Since RegExp.exec returns null on no match, and null is falsy, you can use the assignment to a match variable as a branch condition. An extra level of parentheses may help to placate a linter and put readers on notice that the syntax is intended, but it is not necessary. When people object the C tradition of an assignment expression having a value, they are invariably importing assumptions from some other language and not understanding how C was meant to be used.
Admin
There, I fixed it for you.
The notion of "falsy" is exactly the problem. It doesn't bother me having to write out
if (foo == None) {
instead ofif (!foo) {
if it saves me an hour searching for a difficult to spot 1-character bug.Admin
It's not a problem if you know how it works. It all comes back to a single principle: know your tools, and don't blame them for being something other than what they are.
Admin
It's not necessary to allow an assignment in a Boolean test without any compiler warnings, as other languages have showin. In this day it's perfectly reasonable to require breaking out the operation and let the compiler optimize unnecessary operations. Or to require a Pragma that suppresses the statement warning.
Admin
I do find assign-and-test to be a fun, clever trick; and it probably has legitimate uses in a high-performance environment where you can't spare the bytes for a temporary variable. But outside of that, it doesn't seem to be a good habit, because then you can flag assignment in an
if
as an error and catch bugs before they ever leave your computer.Admin
There's no excuse nowadays for assign-and-test in any compiled language, as any half decent compiler will optimise away the refetch of the data. I can see some temptation to write if (horrendously-complex-lvalue = a), to avoid typing the monster lvalue twice, but even so, there are ways to deal with that (mostly be sorting out your horrendously-complex-lvalue because you've probably used most of it repeatedly already). And if it's a compiled language, creating a temporary variable holding a reference/pointer to the target will, with a moderately efficient optimiser, not cost any machine code. And it's a hell of a lot easier to understand because you don't hit a wall thinking 'did they mean to assign this? or test it?'
It's pretty much the same with interpreted languages. And in any case with interpreted language, performance is a different sort of issue.
The long and the short of this is - write for legibility, not for making the optimisers decisions for it. You'll be grateful when you come back in 3 years.
and yoda expressions are a crime against legibility.
Admin
I'm reminded of the story of the XFree86 project going through and removing every single instance of Duff's Device that they could find. The original Duff's device significantly improved the speed of the code, thanks to it unrolling a loop as well as providing a way to jump into the middle of the loop as necessary.
The result of removing all those excessively clever switch statements? The code sped up significantly, and the binaries were a lot smaller as well. The optimisation that was so useful back in the 80s is no longer useful, thanks to compilers being much better at those micro-optimisations than humans are, generally speaking.
The rule now is: start by writing your code, clearly and concisely, using efficient algorithms. Then, if it's too slow, profile the code and look specifically at the slow points. Don't try to micro-optimise early on, because it's practically certain that you'll do it worse than the compiler could (and likely screw up the compiler's ability to do the job into the bargain.)
Admin
I haven't said anything about runtime performance as a reason for writing code one way or another. As far as I care, the compiler should be able to optimize the code in any case. The point is concise idiom.
Admin
Although I code for a living in C-like languages, this is one reason I kinda prefer how Pascal-like languages instead use := for assignment.
Admin
More to the point, how the Pascalian
;=
doesn't return a value, so it cannot be used in a conditional statement. And that expressions in conditional statements must be of typeboolean
, with no implicit conversion from non-booleans.Addendum 2023-09-21 06:50: Ugh. I meant the Pascalian
:=
Admin
Not only that, but they only protect the misguided fool that uses them against a narrow subset of possible errors. You can't Yoda this, for example:
without changing the bug it causes...
Always always always ask the compiler or linter to error out on "naked" assignments in conditional contexts.
Admin
Which is something C compilers have been doing for years. It doesn't help though, if the dev can go in and change the rules to suppress the warning.
Making assignment an expression that returns a value may have seemed like a good idea to Ken Thompson, but it has caused no end of problems.
Admin
In a high-performance environment (i.e., compiled)
if (a = foo()) { ... }
will generate the exact same assembly asa = foo(); if (a != null) { ... }
. The first will get desugared into the second very early in compilation (like the first pass), way before the compiler is anywhere even close to generating assembly. There's no "extra bytes" for a temporary variable; they're all temporaries.Admin
Your statement is true, but it's also empty, since the negation of it is also true. There is no fundamental reason that assignments must be grammatically distinct from expressions. It's a design choice, just as return and throw expressions are a design choice in Kotlin. Significantly, although JavaScript was based most directly on Java, Eich chose not to follow Java's behavior for conditions but something closer to C's behavior.
Admin
In addition to running everything compiler-related with mandatory -Wall, all warnings should become errors and thus stopping the compilation process. Furthermore, every program that has been successfully compiled and still spits warnings - yes, I am looking at YOU, mostly all "modern" software! - should be taken out and buried in a core dump. Sadly, nobody seems to care. Silence the error printing, so the errors will be gone. Ignore warnings. Ship faulty software, and promise you will soon offer a fix. For an expensive subscription, of course. Then go shopping.
JavaScript error: , line 0: uncaught exception: undefined
(real-world example from an actual program)