「Ifを上げ、Forを下げる」というイディオムは、TigerBeetleのTiger Styleドキュメントに由来し、matkladやDebasish Ghoshなどの開発者によって議論されてきた。その核心原則は、条件文(if)を呼び出し側やデータ処理パイプラインの早い段階に外側へ移し、反復ループ(for)をバッチ処理が可能な後段階へ内側へ移動させることで制御フローを一元化することにある。これにより、関数の前提条件を型で明示し、ホットループをブランチなしで実行できるようにすることで、コードを簡潔にし、明確さとパフォーマンスを向上させることを狙う。
実際に、Ifを上げるとは、内部で無効な入力(Option型のNoneなど)をチェックする関数を、呼び出し側がSuch casesを処理し、関数側が有効な入力であると仮定する形に変換することを意味する。例えば、`frobnicate(walrus: Option<Walrus>)`という内部でNoneをチェックする関数は、呼び出し側でNoneをフィルタリングし、`Vec<Walrus>`を`frobnicate_batch`に渡すように変更できる。このとき`frobnicate_batch`は条件チェックなしでバッチを処理する。同様に、Forを下げるとは、各要素にスカラ関数を呼び出すループを、コレクション全体を処理するバッチ関数に置き換えることを指し、これにより起動コストを償還し、ベクトル化の機会を得ることができる。この変換の代数的基盤は、filter-mapの等価性 `filter p . map f == map f . filter (p . f)` で示される。これは`catMaybes`の自然性から成り立ち、`p . f`が入力データに対する安価な述語に簡約される場合に作業量を削減できる。
ただし、このイディオムが普遍的に適用できるわけではない。ループ内の条件を外に出す変換は、条件がループ不変である場合のみ有効であり、そうでなければデータが変わる場所に判定を残さなければならない。データベースクエリ最適化において、結合の下に選択を押し下げる変換は、結合の片側の列しか参照しない述語に対してのみ安全であり、これによって結合の意味論が変更されないようにする。同様に、filter-mapの書き換えが計算量を削減するのは、`p . f`が生の入力に対する安価な述語に簡約される場合のみであり、そうでなければ書き換えた形式でも依然として各要素に対して`f`を計算した後に述語をテストすることになる。したがって、このイディオムの有効性は、意味を保ちつつコストを潜在的に削減する変換を保証する代数的性質—例えば単形包含や自然性など—を見極める能力にかかっている。
