18 ポイント 投稿者 GN⁺ 2025-04-22 | 11件のコメント | WhatsAppで共有
  • パイプライニングは、プログラミング言語においてコードの可読性と保守性を高める重要な機能
  • データの流れを左から右、上から下へ自然に表現できるようにする方式
  • Rust のような言語では、パイプライニングはコードの流れを明確にし、IDE の自動補完機能によって開発生産性を高める
  • Haskell、Elm、SQL などさまざまな言語で適用され、builder パターンメソッドチェイニングも一種のパイプライニングと見なされる
  • 可読性編集のしやすさIDE サポート、**バージョン管理ツール(diff、blame)**のすべてに良い影響がある
  • 関数をネストする方式より簡潔で明確なコードを書けるため、協業と保守の面でも有利

私がいちばん好きなプログラミング構文、パイプライニング

パイプライニングとは?

  • 前の値を受け渡すことで、引数リストの中の1つの引数を省略できる機能
  • コードの可読性を高め、コメントを追加しやすくしてくれる
  • データを中心に連続した処理を順番に適用する構文スタイル
  • 関数型スタイルのコードでは .map().filter().collect() のようなメソッドチェイニングの形でよく使われる
  • Rust では次のようなコードが代表的な例:
    data.iter()  
        .filter(|w| w.alive)  
        .map(|w| w.id)  
        .collect()  
    
  • 逆にすべての関数をネストすると、次のように内側から外側へ読まなければならない構造になる:
    collect(map(filter(iter(data), |w| w.alive), |w| w.id))  
    

なぜパイプライニングが良いのか?

  • 1. 可読性と保守性

    • 上から下へ読みやすい → 人が読む順序と同じデータフロー
    • 各行にコメントを付けやすい
    • 長い行でも括弧のネストなしで簡潔かつ明確
  • 2. 編集のしやすさ

    • 途中に .map() などの新しい関数を1行で簡単に追加できる
    • git diffgit blame でも変更追跡がすっきり表れる
  • 3. IDE / LSP サポート

    • . キーを押したときに 自動補完リストが出る構造と相性が良い
    • 型を明確に把握していることが前提となる静的解析に有利
    • この機能がきちんと動作するには、言語が静的型付けベースである必要がある(e.g. Rust, TypeScript)

SQL にもパイプライニングはある?

  • SQL のネストした SELECT クエリをパイプラインスタイルに変えられるという提案がある
  • 例:
    FROM customer  
    |> LEFT OUTER JOIN orders ON ...  
    |> AGGREGATE COUNT(...) GROUP BY ...  
    |> ORDER BY ...  
    
  • 従来の SQL より 流れが明確で、可読性が向上
  • 欠点: SELECT 文が上から外れることで返り値の型を把握しにくくなる可能性がある → 解決可能

Builder パターンとのつながり

  • Rust の Builder::new().option().option().build() のような形は典型的なパイプライン構造
  • 任意設定をメソッドで構成しながら、コード追跡や変更管理がしやすい

Haskell におけるパイプライニング改善

  • Haskell の $&, |> のような演算子は、関数合成の代わりにパイプラインを使えるようにする
  • 例の比較:
    -- 기존  
    checkPalindromes content = unlines $ map (show . isPalindrome) $ lines $ map toLower content  
    
    -- 개선  
    checkPalindromes content =  
      content  
        & map toLower  
        & lines  
        & map (show . isPalindrome)  
        & unlines  
    

Rust におけるパイプライニングの利点

  • メソッドチェイニング型推論trait ベースの構造的拡張性がいずれもパイプライニングとうまく噛み合う
  • Rust は関数型とオブジェクト指向の構文の長所だけを取り出したような構造を持ち、パイプライニングの利用が最も自然

結論

  • パイプライニングは単なる構文ではなく、コードの流れ、編集性、協業にまで影響する中核機能
  • f(g(h(x))) のようなネストより、x |> h |> g |> f の構造のほうが人間にやさしい
  • パイプライニングは「1行に1つの処理」という単純なルールのもとで、自然な流れを表現できる最良の方法

「各パイプの断片は主要なデータを受け取り、1つの処理を行う。最後に明確な名前を付ければ、それが最も理想的なコード構造だ。」

11件のコメント

 
tested 2025-04-23

私がいちばん好きなプログラミング構文、"パイプライニング"

https://github.com/tc39/proposal-pipeline-operator

 
progdesigner 2025-04-23

どんなテキストでも
改行やインデントが可読性に重要なのと
似た文脈だと思います。

 
forgotdonkey456 2025-04-23

LINQ最高!

 
bus710 2025-04-23

Gleamもこれをサポートしているので、かなりすっきりコードが書けるんですよね。

ところで、本文にコードブロックが入っているからなのか、モバイルでもデスクトップレイアウトで表示されますね。

 
bus710 2025-04-23

そういえば、elmでもできますね。

 
galadbran 2025-04-22

少量のデータや上の例のような簡単なレベルのコードでは、見た目も悪くないと思います。

ですが map() の中にコードが少しずつ入り始めると……コードがだんだん太っていく傾向がありますし、
言語や実装ライブラリによって影響はありますが、データ量が多くなると、単にデータ構造にデータを積んだり操作したりしながら処理するのに比べて、簡単に数千倍遅くなることもあるので、

それに、さらに好まなくなった新しい理由がもう一つできたのですが、スマホでこの記事を見たら、PCレベルの幅がそのまま維持されて文字サイズがゴマ粒みたいに小さくなってしまい、記事を読むのがとても大変だったからです T.T

基本的には好みではなく、わざわざああいう書き方をしようとはしません。

 
bichi 2025-04-22

JSもください |> ぺこぺこ

 
secret3056 2025-04-22

|> がとてもきれいです

 
howudoin 2025-04-22

私が一番嫌いな文法だ
stack traceが少しでもこじれていると、デバッグは最悪だ

 
cosine20 2025-04-25

マジそれな

 
GN⁺ 2025-04-22
Hacker Newsの意見
  • 筆者はこれを "pipelining" と呼んでいるが、正しい用語は "method chaining" だと思う

    • Bashの単純なパイプラインとの比較: 各構成要素は並列に実行され、中間結果はストリーミングされる
    • Rubyでは各行が順次処理され、各段階の間に完全な配列が生成される
    • デバッグが難しくなるため、最近はより明示的なコードを書くようにしている
    • 明示的なコードは見た目はあまりすっきりしないが、中間状態を簡単に確認できる
  • 個人的には、言語の機能セットを小さく保ち、素早く完成した機能セットに到達することを支持している

    • しかし Elixir の |> 構文は、すべての言語が採用してほしいと思っている
  • Lispマクロは、チェーンされたコレクション演算子だけでなく、呼び出しチェーンの順序を決定できる一般的な解決策を提供する

    • たとえば、(foo (bar (baz x))) を (-> x baz bar foo) と書ける
    • 追加の引数がある場合でも処理可能
    • 詳細は Clojure のスレッディングマクロガイドを参照
  • この用語は fluent interface として学んだ。パイプライニングは別物だ

  • パイプライン演算子は部分適用の一種で、複数の引数を束縛して新しい関数を作り、その出力を別の関数に渡せる

    • 部分適用はプログラムを書くうえで非常に有用で、いつか(非Haskell系の)言語もこれをプログラム構成の基本として使うようになるだろう
  • Rの tidyverse ユーザーはすでにこれを使っている

  • パイプライニングはデバッグが難しい。例外処理も難しく、パイプラインに分岐を追加しなければならない

    • パイプラインはハッピーパスをプログラミングするときにしか有用ではない
  • SQLの構文は不必要に複雑だ

    • SQLはすでに演算子言語だが、歴史的な理由で制約が多い
    • 新しい構文を許すのなら、もっとシンプルに書けるはずだ
    • |> 構文には表現力がなく、視覚的ノイズを増やす
  • 筆者は「意味が構文に勝る」と主張しているが、実際には構文の好みに焦点を当てている

    • パイプライニングはチェーンが長くなるほどデバッグが難しくなる
    • Pythonに批判的だが、具体的な理由は示していない
    • "pipelining" の定義が明確ではない
  • effect-ts はパイプラインと命令型コードの両方を書けるようにしている

    • パイプラインの書き方とジェネレーターの使い方に関するドキュメントを提供している
    • コミュニティの大半は命令型スタイルのジェネレーターを好むようになった
    • そのほうがデバッグや保守がしやすいように見える