1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

フックとフォーク ― J 言語入門

Last updated at Posted at 2021-06-27

J 言語の最も面白い機能の一つが、フックとフォークです。

フック

ちょうど 2 つの連続する verb があり、その直後に noun が続いていないとき、その verb の組をフック (hook) と呼びます。

以下がフックの例です。

* |
% +/           NB. (+/) は 1 つの verb
(% +/) 3 16 7  NB. 括弧の外に noun が続いているが、括弧の中身はフック

フック g h は、次のような動作をする verb を作ります。

  • dyad x (g h) yx g (h y)
  • monad (g h) yy 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 hf の部分には、noun を使うことも可能です (それ以外の場所には使えません)。

   (1 + i.) 10
1 2 3 4 5 6 7 8 9 10

f yx 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 ]

  1. 厳密には @: と同じになります。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?