道しるべがないままのFactor入門第二回。

今回は、ForthにはなかったQuotationについて。まずは実例から。

( scratchpad ) 2
--- Data stack:
2
( scratchpad ) [ 3 * ] ! これがQuotation
--- Data stack:
2
[ 3 * ]
( scratchpad ) call . ! [ 3 * ] が評価・実行される
6
( scratchpad )

[]で囲った中身は、すぐには評価されないカタマリになるようです。それがquatation。ドキュメントでQuatationをひいてみると、こんなことかいてあります。

Conceptually, a quotation is an anonymous function (a value denoting a snippet of code) whichcan be passed around and called.

Concretely, a quotation is an immutable sequence of objects, some of which may be words, together with a block of machine code which may be executed to achieve the effect of evaluating the quotation. The machine code is generated by a fast non-optimizing quotation compiler which is always running and is transparent to the developer.

概念としては無名関数。具体的には、オブジェクトのシーケンス、だそうです。無名関数ぽい使い方といえば、mapとかeachですかね。

( scratchpad ) : concat ( array -- seq ) "" swap [ append ] each ;
( scratchpad ) { "dobin" "chobin" "hagechobin" } concat .
"dobinchobinhagechobin"
( scratchpad ) { "dobin" "chobin" "hagechobin" } [ reverse ] map .
{ "nibod" "nibohc" "nibohcegah" }
( scratchpad ) : palindrome? dup reverse = ;
( scratchpad ) { "dobin" "chobin" "tattarrattat" "hagechobin" } [ palindrome? ] map .
{ f f t f }

Factorでは、if文などの制御構造でもこのquatationをつかいます。

( scratchpad ) : positiveYN ( n -- ) 0 > [ "Yes" ] [ "No" ] if print ;
( scratchpad ) 3 positiveYN
Yes
( scratchpad ) -1 PositiveYN
No

んー、Forthのifよりは、一貫性がある感じかな。ちょっと読みづらいけど。