Factorへようこそ! Factorは連結型の言語です。square(add(2, 3))のように関数を呼び出すのではなく、ワードを左から右へと並べて書きます(2 3 + square)。ワード同士は、共有されたデータスタックを通じて値を受け渡します。埠頭に積み上げられた貨物のクレートを思い浮かべてください。新しい荷物ほど上にあります。
!で行コメントが始まります。Factorは!から行末までのすべてを無視します。以下の例では、コードが何をするのかを注記するために!を使っています。
リテラルを書くと、その値がスタックの一番上に積まれます。コードは左から右へ読まれます。
1 2 3 ! stack (bottom → top): 1 2 3
どのワードも、スタックの一番上から入力を受け取り、結果をそこへ書き戻します。.は一番上の値を取り出して表示します。.sは何も消費せずに、スタックの全体を表示します。これは、あるコード片が何を残したかを確認するのに便利です。
どのワードも、( inputs -- outputs )という形式のスタック効果で記述されています。これはワードの契約です。ワードはスタックの一番上から入力を取り出し、その場所に結果を残します。中に書かれた名前は人間のための説明であり、スタックそのものは名前ではなく位置で扱われます。スタックの一番上は、右端の名前です。
:でワードの定義が始まり、次にスタック効果、続いて本体、最後に;で終わります。Factorのコンパイラーは、本体が本当にスタック効果で宣言したとおりの結果を残すかどうかを検査します。
: restow ( a b -- b a ) swap ;
これらのkernelのワードは、計算を一切せずにスタックの一番上を並べ替えます。クレートを動かすだけです。
dup ( x -- x x ) ! copy the top crate
drop ( x -- ) ! remove the top crate
swap ( x y -- y x ) ! flip the top two
over ( x y -- x y x ) ! copy the second crate onto the top
nip ( x y -- y ) ! remove the second crate
rot ( x y z -- y z x ) ! roll the third crate up to the top
1つのクレートを2つのワードに渡したいときはdup、クレートを捨てたいときはdrop、一番上の2つが逆になっているときはswap、下にあるクレートを扱いたいときはoverかnip、埋もれたクレートを一番上に持ち上げたいときはrotを使います。
より広い仲間(-rot、dupd、swapd、2dupなど)も同じ考え方に従います。これらのワードには、このあと出会います。
並べて書かれたワードは左から右へ実行されます。それぞれのワードは、その前のワードが残したスタックに対して働きかけます。swap nipがスタック1 2(下→上)に対して、1ワードずつ何をするかを示します。
1 2 ! 1 2 the starting crates
swap ! 2 1 swap flipped the top two
nip ! 1 nip dropped the 2nd-from-top crate (the 2)
次に、同じ最初のクレートに対するdup rotを、これも1ワードずつ見てみます。
1 2 ! 1 2 the starting crates
dup ! 1 2 2 dup copied the top crate
rot ! 2 2 1 rot rolled the 3rd-from-top crate up to the top
ワードにはlowercase-kebab-caseを使います。小文字をハイフンでつないだ形です。
波止場で貨物箱を積み直す甲板員です。各タスクは1つのワードで、その本体ではシャッフルワードだけを使います。算術は使いません。
swap-cratesワードを定義します。スタックから箱を2つ取り出し、それらを逆の順序でスタックに残します。
1 2 swap-crates .s
! 2
! 1
clear-spillワードを定義します。スタックから箱を3つ取り出し、下の2つを残して、一番上の箱は捨てます。
1 2 3 clear-spill .s
! 1
! 2
peek-underワードを定義します。スタックから箱を2つ取り出し、下の箱のコピーを一番上に置いて、それらをスタックに残します。
1 2 peek-under .s
! 1
! 2
! 1
tidy-deckワードを定義します。スタックから箱を3つ、x y zの順に取り出し、z z yを残します。つまり、一番下の箱は捨て、一番上の箱のコピー2つを真ん中の箱の下に残します。
1 2 3 tidy-deck .s
! 3
! 3
! 2