パイプラインスタイル

たとえば、関数 ABCD のシーケンスを合成したいとします。連鎖性言語では、次のように記述するだけです。

A B C D

適用型言語では、たとえば次のようなコードを記述することになります。

(D (C (B (A x))))

これはまさに「後向き」に見えます。なぜなら、右から左へとコードを読まなければならないからです。A が最初に実行すべき関数で、次が B、そして C、その次が D です。Haskell では、関数合成のためのインフィックス演算子があるので、過剰な入れ子は避けることができますが、コードの順序はやはり「後向き」になります。

D . C . B . A

Factor の世界では、こうしたコードを「パイプラインコード」と呼びます。

パイプラインコードは、スタック型言語では最もシンプルな語法の 1 つで、各ワードはスタックから値を 1 つ取り出し、新しい値をスタックに積みます。このようなワードは、ちょうど Unix のシェルで複数のコマンドをつなげるように、どんどんつなげていくことができます。たとえば、Factor のコードで例を示せば次のようになります。

"/etc/passwd" ascii file-lines
[ "#" head? not ] filter
[ ":" split first ] map

これは、Unix のシェルスクリプトで次のように記述した場合とよく似ています。

cat /etc/passwd | grep -v '^#' | sed -e 's/:.*//'

パイプラインコードのバリエーションは、UI フレームワークにもあります。以下の例で作成するのはガジェットのツリーなので、必ずしもパイプラインというわけではありませんが、子ガジェットを作成し、これらを束ね、add-gadget ( parent child -- parent ) を使って親ガジェットに追加します。コードは次のとおりです。

USING: ui.gadgets.packs ui.gadgets.labels ui.gadgets.borders
ui.gadgets ui.gadgets.buttons ui.backend ui.render ui colors.constants
ui.pens.solid ;

<pile>
    "Hello" <label> add-gadget
    "Click me" [ drop beep ] <border-button> add-gadget
    <shelf>
        "A" <label>
            COLOR: red <solid> >>interior
        add-gadget
        "B" <label>
            COLOR: green <solid> >>interior
        add-gadget
        "C" <label>
            COLOR: blue <solid> >>interior
        add-gadget
    add-gadget
5 <border>
    COLOR: black <solid> >>boundary
"Test" open-window

ほとんど宣言文のように見えるかもしれませんが、実際にはスタックコードであることに注意して読んでみてください。

This revision created on Tue, 21 Jul 2009 22:46:16 by littledan (fixing Factor example)