It's really about finding the entry points into your program from the outside (including data you fetch from another service), and then massaging in such a way that you make as many guarantees as possible (preferably encoded into your types) by the time it reaches any core logic, especially the resource heavy parts.
Push Ifs Up and Fors Down
21–30 of 209 posts
Re: Push Ifs Up and Fors Down
#22Terrible advice. It's the exact opposite of "Tell, don't ask". Performance of an if-statement and for-loop are negligent. That's not the bottleneck of your app. If you're building something that needs to be highly performant, sure. But that's not the majority. https://martinfowler.com/bliki/TellDontAsk.html
Re: Push Ifs Up and Fors Down
#23Code complexity scanners⁰ eventually force pushing ifs down. The article recommends the opposite: By pushing ifs up, you often end up centralizing control flow in a single function, which has a complex branching logic, but all the actual work is delegated to straight line subroutines. ⁰ https://docs.sonarsource.com/sonarqube-server/latest/user-gu...
Re: Push Ifs Up and Fors Down
#24Terrible advice. It's the exact opposite of "Tell, don't ask". Performance of an if-statement and for-loop are negligent. That's not the bottleneck of your app. If you're building something that needs to be highly performant, sure. But that's not the majority. https://martinfowler.com/bliki/TellDontAsk.html
Re: Push Ifs Up and Fors Down
#25Re: Push Ifs Up and Fors Down
#26Code complexity scanners⁰ eventually force pushing ifs down. The article recommends the opposite: By pushing ifs up, you often end up centralizing control flow in a single function, which has a complex branching logic, but all the actual work is delegated to straight line subroutines. ⁰ https://docs.sonarsource.com/sonarqube-server/latest/user-gu...
Well, now I have an answer...
Re: Push Ifs Up and Fors Down
#27Code complexity scanners⁰ eventually force pushing ifs down. The article recommends the opposite: By pushing ifs up, you often end up centralizing control flow in a single function, which has a complex branching logic, but all the actual work is delegated to straight line subroutines. ⁰ https://docs.sonarsource.com/sonarqube-server/latest/user-gu...
Re: Push Ifs Up and Fors Down
#28This article doesn't explain the benefits of the suggested approach well enough. And the last example looks like a poor advice and contradicts previous advice: there's rarely a global condition that is enough to check once at the top: the condition usually is inside the walrus. And why do for walrus in pack {walrus.throbnicate()} instead of making throbnicate a function accepting the whole pack?
Re: Push Ifs Up and Fors Down
#29I agree, except for this example, where the author effectively (after a substitution) prefers the former: fn f() -> E { if condition { E::Foo(x) } else { E::Bar(y) } } fn g(e: E) { match e { E::Foo(x) => foo(x), E::Bar(y) => bar(y) } } The latter is not only more readable, but it is safer, because a match statement can ensure all possibilities are covered.
> The latter is not only more readable, but it is safer, because a match statement can ensure all possibilities are covered. Whether or not this matters depends on what, exactly, is in those match arms. Sometimes there's some symmetry to the arms of an if statement. And in that case, being exhaustive is important. But there's plenty of times where I really just have a bit of bookkeeping to do, or an early return or s…
Re: Push Ifs Up and Fors Down
#30 fn frobnicate(walrus: Option)`)
but the rest makes no sense to me! // GOOD
frobnicate_batch(walruses)
// BAD
for walrus in walruses {
frobnicate(walrus)
}
It doesn't follow through with the "GOOD" example though... fn frobnicate_batch(walruses)
for walrus in walruses { frobnicate(walrus) }
}
What did that achieve?And the next example...
// GOOD
if condition {
for walrus in walruses { walrus.frobnicate() }
} else {
for walrus in walruses { walrus.transmogrify() }
}
// BAD
for walrus in walruses {
if condition { walrus.frobnicate() }
else { walrus.transmogrify() }
}
What good is that when... walruses = get_5_closest_walruses()
// "GOOD"
if walruses.has_hungry() { feed_them_all() }
else { dont_feed_any() }
// "BAD"
for walrus in walruses {
if walrus.is_hungry() { feed() }
else { dont_feed() }