Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

Fried quotation

0.92の新機能(になるはず)
Fried quotationの使い方。
結構手抜き。

Fried quotation

なんでfryなのか良くわかってないんですがそう呼ばれています。
fryはquotの任意の場所にstackの値をマッピングする事が出来ます。

Fried quotationはcurryとcomposeをする時のショートカットとして使用されます。
簡単な例を元に説明していきます。

USING fry ;
2 3 '[ 1 , + , 4 / ] .
[ 1 2 + 3 4 / ]

結果は[ 1 2 + 3 4 / ]というquotになります。
まあパッと見て,をマッピングしてくれてるのがわかりますね。

まずFried quotationを使用するには'[から始まり、]で囲みます。
このquotはfry callを呼んでいるのと同等になります。

'[ X ]
[ X ] fry call

Fried quotationがマッピングするのは以下の3つです。
マッピング以外の効果を及ぼすものもあります。

  1. , リテラルマッピング
  2. @ quotを展開してマッピング
  3. _ _直前までをquotで囲みdipを呼ぶ

上記の例だとひとつめの,に2、そして2つめ(右側)の,には3がマッピングされます。
,の数だけ右から順にstackから値を取り出しマッピングします。
Fried quotationはあくまでquotなので結果はマッピングされたquotになります。

マッピング

Fried quotationはスタック指向では単純に処理しにくいケースなどを柔軟に
表現できます。それはマッピングによる所が大きいでしょう。
トリッキーではありますが使い所によってはとても処理をシンプルにしてくれます。

では,の簡単な例をあげてみます。以下は全て等価です。

{ 10 20 30 } 5 '[ , + ] map
{ 10 20 30 } 5 [ + ] curry map
{ 10 20 30 } [ 5 + ] map

@の例です。以下は全て等価です。sqのquotが展開されてる点に注目です。

{ 10 20 30 } [ sq ] '[ @ . ] map
{ 10 20 30 } [ sq ] [ . ] compose map
{ 10 20 30 } [ sq . ] map

,と@などmixして使うことも出来ます。

{ 8 13 14 27 } [ even? ] 5 '[ @ dup , ? ] map
{ 8 13 14 27 } [ even? ] 5 [ dup ] swap [ ? ] curry 3compose map
{ 8 13 14 27 } [ even? dup 5 ? ] map

_の例は割愛します。

どこで使うのか

問題はどこでこのtrickは使うかです。
あくまでFried quotationはquotです。
そのため引数にquotに取るwordと共に使います。
これはhttp.client vocabularyでの使用例です。

: close-on-error ( stream quot -- )
'[ , with-stream* ] [ ] pick '[ , dispose ] cleanup ; inline


: http-request ( request -- response stream )
dup request [
dup request-addr latin1
1 minutes over set-timeout
[
write-request flush
read-response
do-redirect
] close-on-error
] with-variable ;

close-on-error word内で使用しています。
cleanup wordはtry-finallyあるいはunwind-protectと同様なwordと
思ってもらってかまいません。
ここではうまく一つ目の,にquotを渡し、そのquotに対しをwith-stream*を適用しています。
そしてpickでstreamを次のdiposeのあるquotにマッピングしています。
この時点でquotが3つにclenup wordという状態になります。
そしてcleanupを実行してエラー発生時にはstreamを破棄する処理を実現しています。

このようにFried quotationは以下のケースで威力を発揮します。

  1. with-系の処理を使いまわすwordの定義
  2. quotを引数にとるwordへ渡たすquotの生成

ローカル変数なんて飾りです。偉い人にはそれがわからんのです
次回のTIPSは0.92からの機能である[let、[let*、named-parameterの説明の予定です。