HN.zip

Push ifs up and fors down: The idiom, its algebra, and its limits

63 points by speckx - 20 comments
socializer [3 hidden]5 mins ago
I am continually impressed by the ability of LLMs to take trivial ideas and turn them into lengthy and obtuse blog posts with unnecessary analogies.
swiftcoder [3 hidden]5 mins ago
Honestly, this just looks like one of those lingo-heavy-but-surface-level blog posts that used to make functional programming spaces so insufferable to everyone on the outside
mahboi [3 hidden]5 mins ago
These things are so divorced from the reality of programming, even when they involve actual code instead of fancy lingo. Like in Scala, not a pure functional language, tutorials used to find the most convoluted higher-order functional way to do simple things.
bioneuralnet [3 hidden]5 mins ago
Yet another encroachment on traditionally human activity.
moritzwarhier [3 hidden]5 mins ago
I am the

  Option<Walrus>
msdz [3 hidden]5 mins ago
I know we’re not supposed to comment just for that, but this might be my single favorite joke comment I’ve ever read here. Good job.
jibalt [3 hidden]5 mins ago
Except that TFA is a bog standard example of traditional human activity and the GP's comment is nonsensical trolling.
ninalanyon [3 hidden]5 mins ago
I've done this for years. Not every time of course but where it makes the code easier to understand and maintain.

Speed was almost never the reason.

alterom [3 hidden]5 mins ago
I take it you never rewrote a Matlab for loop as a vector/matrix op for insane speedups then :)
wallstop [3 hidden]5 mins ago
What is missing here is any benchmarks backing up this argument for code structure.

Of note, as of C#9 (and maybe prior), the dotnet runtime does this automatically whenever it is deemed safe. https://devblogs.microsoft.com/dotnet/performance-improvemen...

The same technique is applied as an optimization, when deemed safe, in all current gen c compilers (gcc, llvm, etc).

I'm very confused why neither measurements nor references to when this is done automatically in most modern languages is included in the article.

cogman10 [3 hidden]5 mins ago
At least in JVM land, it's pretty easy to thwart that optimization. Particularly if the condition is on a mutable yet unchanged in the loop value.

For example:

    var map = new HashMap<String, String>();
    map.put("foo", "bar");
    for (var i : items) {
      if ("bar".equals(map.get("foo")) {
        doStuff(i);
      }
    }
Even though `map` isn't mutated, it's hard enough for the JVM to detect and the underlying `get` functions are complex enough that it'll run the `get("foo")` every time, which can be quiet expensive.
throwawayffffas [3 hidden]5 mins ago
Just the branch predictor gains are probably worth it.
dieselgate [3 hidden]5 mins ago
Didn’t see it mentioned in the article but isn’t leading with if-statement called a “guard clause”. I like that pattern but it’s just general best practice I thought.
mahboi [3 hidden]5 mins ago
Guard clauses are things that return early for trivial or problematic cases. Like https://en.wikipedia.org/wiki/Guard_(computer_science)#Flatt...

They're one of those good practices that look like bad practice to everyone who just got a CS degree. Seems ex-students are unsettled by asymmetry or want to minimize the number of return statements.

woadwarrior01 [3 hidden]5 mins ago
Swift explicitly has a guard statement for this. Rust's let .. else { ... } is also very similar.

https://docs.swift.org/latest/documentation/the-swift-progra...

aappleby [3 hidden]5 mins ago
I have always phrased this as "Never do one of something".
OutOfHere [3 hidden]5 mins ago
I like it, but to do fizzbuzz in this way, you'd have to separate what's inside the loop into a reused function.
pdpi [3 hidden]5 mins ago
I think it's sort of obvious that the limit to this general rule is when data dependencies between fors and ifs forbid you from pushing things further up/down.
taolson [3 hidden]5 mins ago
Or just use lazy list operations with a single if test at the end:

https://github.com/taolson/Admiran/blob/main/examples/fizzBu...

/s

alterom [3 hidden]5 mins ago
TL;DR in one sentence:

"the loop runs without a branch, and is a candidate for vectorization".

That's it, that's the article. This matters a lot in huge-scale / scientific computing / HPF, where if you can express something as an operation on vectors on matrices, you win big (those ops parallelize well, can be run on GPUs, clusters, what have you).