J 言語の最も面白い機能の一つが、フックとフォークです。
フック
ちょうど 2 つの連続する verb があり、その直後に noun が続いていないとき、その verb の組をフック (hook) と呼びます。
以下がフックの例です。
* |
% +/ NB. (+/) は 1 つの verb
(% +/) 3 16 7 NB. 括弧の外に noun が続いているが、括弧の中身はフック
フック g h
は、次のような動作をする verb を作ります。
- dyad
x (g h) y
はx g (h y)
- monad
(g h) y
はy g (h y)
g
/ \
x|y h
|
y
使い方
dyad として そのまま使う場合、普通に verb を使っても同じです。
NB. | (monad) は絶対値を求める
2 (* |) _3
6
2 * |_3
6
フックの利点は、modifier の被演算子として使うことができることです。
2&(* |)
2&(* |)
2&(* |) _3
6
一方、monad の場合は、普通に verb を使うのとは違う動作をします。
(% +/) 3 8 5
0.1875 0.5 0.3125
% +/3 8 5
0.0625
NB. 同じ動作をさせるには、引数を 2 回書く必要がある
3 8 5 % +/3 8 5
0.1875 0.5 0.3125
フックは式の中で使うときは括弧で囲みます。括弧を付けないと、上の例のように違う意味になってしまいます。ただし、フック自体を変数に代入する場合は括弧は不要です。
NB. リストの各要素の、全体に対する比率を求める verb
proportion=: % +/
proportion 3 8 5
0.1875 0.5 0.3125
フォーク
フォーク (fork) は、フックと似ていますが、3 つ組の verb です。
* , +
+/ % #
フォーク f g h
は、次のような動作をする verb を作ります。
- dyad
x (f g h) y
は(x f y) g (x h y)
- monad
(f g h) y
は(f y) g (h y)
g
/ \
f h
[/]\ [/]\
[x] y [x] y
使い方
フックとは異なり、括弧の有無で大きな違いがあります。
NB. (2 * 3) , (2 + 3)
2 (* , +) 3
6 5
2 * , + 3
6
有名な例ですが、リストの平均値 (算術平均) を求める verb をフォークを使って書くことができます。
average=: +/ % #
average 10 7 23
13.3333
「総和 (+/
) 割る (%
) 要素数 (#
)」という定義通りの記述になっています。
noun - verb - verb
フォーク f g h
の f
の部分には、noun を使うことも可能です (それ以外の場所には使えません)。
(1 + i.) 10
1 2 3 4 5 6 7 8 9 10
f y
や x f y
を実行する代わりに、f
の値が使われます。
g
/ \
f h
[/]\
[x] y
cap
[:
は、cap と呼ばれる verb です。この verb は、実行すると必ずエラーが発生します。
[:''
|domain error
| [:''
0 [: 1
|domain error
| 0 [:1
一見使いどころが無さそうに見えますが、フォークの f
の部分に使うと、特殊な効果があります。
NB. % (1 + 2)
1 ([: % +) 2
0.333333
フォークの f
側の部分が削除されて、@
と同じような動作になります 1。このとき、[:
自体は実行されません。
g
|
h
[/]\
[x] y
4 つ以上の verb
verb が 4 つ以上連続する場合も、フォークやフックとして解釈されます。ここでも、右から左のルールが適用されます。
(a4 a3 a2 a1) => (a4 (a3 a2 a1))
(a5 a4 a3 a2 a1) => (a5 a4 (a3 a2 a1))
(a8 a7 a6 a5 a4 a3 a2 a1) => (a8 (a7 a6 (a5 a4 (a3 a2 a1))))
(a9 a8 a7 a6 a5 a4 a3 a2 a1) => (a9 a8 (a7 a6 (a5 a4 (a3 a2 a1))))
右から順に 3 つ組の verb をフォークとして読んでいき、最後に余りが出た場合は、その部分 (一番左) がフックになります。
例
フックとフォークの例をいくつか載せておきます。実行しながら理解を深めましょう。
NB. データ型と値のペア
(;~ datatype) 0 1
(;~ datatype) 'a'
NB. x 以上 y 未満の整数のリスト
NB. ([ + ([: i. -~))
3 ([ + [: i. -~) 12
_2 ([ + [: i. -~) 5
NB. 以下はヒントなし
4 ({ ,) i.3 3
(2 + -)&(1) 3
1 (+ + + + + +) 1
1 (+ + + + + + +) 1
1 (+ + + + + + + +) 1
これがスラスラ読めるようになると、J が楽しくなってくると思います。
[ 前 : 代入 ] [ 目次 ] [ 次 : explicit definition ]
-
厳密には
@:
と同じになります。 ↩