The idiom 'push ifs up and fors down' originates from the Tiger Style document of TigerBeetle and has been discussed by developers such as matklad and Debasish Ghosh. Its core principle is to centralize control flow by moving conditional statements (if) outward toward the caller or earlier in a data processing pipeline, while relocating iterative loops (for) inward toward later stages where data can be processed in batches. This separation aims to simplify functions by making their preconditions explicit in their types and enabling hot loops to run without branches, thus improving clarity and performance.
In practice, pushing conditionals up means transforming a function that internally checks for invalid inputs (like None in an Option type) into one where the caller handles such cases and the function assumes valid input. For example, a function `frobnicate(walrus: Option<Walrus>)` that checks for None inside can be changed so the caller filters out None values and passes a `Vec<Walrus>` to `frobnicate_batch`, which then processes the batch without any conditional checks. Similarly, pushing loops down involves replacing a loop that calls a scalar function per element with a batch function that processes the entire collection, allowing for amortized startup costs and opportunities for vectorization. The algebraic basis for such transformations is illustrated by the filter-map equivalence: `filter p . map f == map f . filter (p . f)`, which holds due to the naturality of `catMaybes` and saves work when `p . f` reduces to a cheap predicate on the input data.
However, the idiom is not universally applicable. Moving a conditional out of a loop is valid only when the condition is loop-invariant; otherwise, the decision must stay where the data varies. Pushing a selection below a join in database query optimization is safe only when the predicate references columns from a single side of the join, ensuring the join's semantics are unchanged. Likewise, the filter-map rewrite saves computation only when `p . f` simplifies to an inexpensive predicate on the raw input, because otherwise the rewritten form still computes `f` for every element before testing. Thus, the idiom's effectiveness depends on recognizing algebraic properties—such as monomorphism inclusion or naturality—that guarantee the transformation preserves meaning while potentially reducing cost.