If I'm reading a loop and see
for x in y {
if exclusions.contains(x) {skip;}
if x.children.length == 0 {skip;}
if os.file.exists(x.name) {skip;}
...
I instantly know that processing for those elements is skipped, and they won't be relevant for the rest of the loop.Whereas if I see
for x in y {
if !exclusions.contains(x) {
if x.children.length != 0 {
if !os.file.exists(x.name) {
...
I feel like there's still mental overload with not knowing where those `if` blocks end, and so having to keep the conditions in mind. It doesn't immediately tell me that the rest of the loop is being skipped.The `log()` mistake seems no less likely to happen using early-returns in function instead, and I'd argue nesting checks actually introduces more room for that kind of error overall, where you append something at the end within the wrong set of brackets, compared to a flatter structure.
zoezoezoezoe•3h ago
``` for (Node node : nodeList) { if (node.isBad()) { continue; } processNode(node); } ```
Every keyword in any programming language is largely arbitrary in my opinion let's take a look at the beginning of the codeblock `for (Node node : nodeList)` also completely arbitrary, though it's clear to anyone who's ever written C++ that it is equivalent to saying "for every node in nodeList".
Continue is not meant to read as "continue execution" it's meant to be "continue to the next item of the list", and I think avoiding it entirely is a pointless effort.