APL/J言語比較入門


わたしはJ言語はAPLの正統な後継言語でJ言語で十分だという主義ですが、歴史もあるし過去の栄光もあるのでAPLの文献を読む必要があったり、読みたかったりする人も多いと思います。というわけで、APLを読みながらJ言語を勉強できるような工夫を考え中。

基本

   1+1
2

は同じなのですが、

   1000000*10000
1e10

は違いますね。APLではx(かける,times)で掛け算ですが、J言語では*(アスタリスク)です。J言語にはx(エックス)は別途用途があって、自然対数の値です。厳密にはフォントは違うのでしょうが、見た目では区別はできない。

   1x1
2.71828
   1p1
3.14159
   1e1
10
   1x2
7.38906
   2x1
5.43656

APLでは割り算は÷(divide、わる)を使いますが、J言語では%(パーセント)を使います。

   10 % 3
3.33333

さて変数への代入ですが、APLでは←(ひだりやじるし)を使います。

   A←10+1 2 3
   A
11 12 13

J言語では=.(イコールドット)または=:(イコールコロン)を使います。

   a =: 10+1 2 3
   a
11 12 13

違いもなんですが、似ていますよね。基本的には同じ言語と言っていいくらい似ています。J言語の動詞(他言語での関数や演算子のこと)ではアスキー文字一文字かそれににドットかコロンをついたものになっています。
上の例を見てわかるように、数字をスペースで区切ってならべるとすでに配列で、10+1 2 3 は11 12 13とになります。あと、APLはアルファベットは大文字ですが、J言語では普通小文字を使うようです。大文字と小文字は区別されます。
代入と同時に画面に出力したいとき、APLでは⎕(クワッド)というしろしかくを使います。

   ⎕←A←1+1
2

J言語ではおなじようなことをするには](右角カッコ)か[(左角カッコ)を使います。

   [ a =: 1+1
2
   ] a =: 1+1
2

APLでもJ言語でも数式は右から順に実行されます。また結果に対して処理を続行していくことができます。

   R←⎕←(S←1000)+(T←1980)xK←12
24760

同じことをJ言語でやってみよう。

   ]r=:(s=:1000)+(t=:1980)*k=:12
24760

結果は同じだけど⎕(クワッド)の位置と、](右角カッコ)の位置が違いますね。ちなみにこの文章書きながらJ言語はj602で実行してコピーしていますが、APLは実行環境を持っていません。Windows用のフリーのもいろいろあるようなのですが、わたしの環境ではうまく動いていません。

配列

APLではρ(ろー)を使うところをJ言語では$(ドル、シェイプ)を使い方はだいたい同じです。

   B←2 3ρA←⍳6
   A
1 2 3 4 5 6
   ρA
6
   B
1 2 3
4 5 6
   ρB
2 3
   b=:2 3$a=:i.6
   a
0 1 2 3 4 5
   $a
6
   b
0 1 2
3 4 5
   $b
2 3

APLで⍳(いおた)でやることはJ言語ではi.(アイドット)でできます。つまり0または1からある数までの整数の配列なのですが、ひとつ違いがあって、APLは1ベースでJ言語ではゼロベースです。昔の本を読むと1から始まるのを自慢そうに書いてありますが、やっぱこれはゼロスタートが正しいと思う。どっちでもいいけど。

   A[3]
3
   B[1:3]
3
   B[;3]
3 6
   C←'ABCDEF'
   C[2 2ρ4 3 2 1]
DC
BA

むむう、だんだんむずかしくなってきました。配列の要素の取り出しですが、J言語では{(左波カッコ、左ブレイス)を使います。

   a
0 1 2 3 4 5
   2{a
2
   b
0 1 2
3 4 5
   (< 0 2){b
2
   (<(<'');2){b
2 5
   (< a: ; 2){b
2 5
   2 {"1 b
2 5
   2 2$(3;2;1;0){c
dc
ba

説明は下手に説明するより、J言語のJ Primerの"From -- boxed indexes"を読むのがよいでしょう。

副詞

APLでもJ言語でも同じ/(スラッシュ)という副詞について説明します。副詞は動詞と一緒に用いられて、動詞を補完するものです。/(すらっしゅ)を使うと配列の間に動詞を置いたのと同じ結果を得ます。

   +/A
21
   +/B
6 15
  +/[1]B
5 7 9
   +/a
15
   a
0 1 2 3 4 5
   +/b
3 5 7
   +/"1 b
3 12

を多次元配列の軸の考え方がAPLとJ言語では違うようですね。

   +\A
1 3 6 10 15 21

副詞\(バックスラッシュ)の用法が似ててちょっと違うようで、上記のAPLの例は配列の累積を計算していますが、同じようなことをJでやろうとすると下記のようになると思う。

   +\a
0 0 0 0 0 0
0 1 0 0 0 0
0 1 2 0 0 0
0 1 2 3 0 0
0 1 2 3 4 0
0 1 2 3 4 5
   +/"1 +\a
0 1 3 6 10 15

つまり、J言語では\(バックスラッシュ)はテーブルを作る副詞で、このテーブルを横方向に足すと求める数列なので、+/"1とします。"1は足す際の次元を変えるconjunction(接続詞)です。

[つづく]