J には、もう一つ重要な型、ボックス型 (boxed type) があります。
C# や Java 等を知っている人なら「ボックス化 (ボクシング)」という言葉を聞いたことがあると思います。同じ用語を使いますが、実際は似て非なる機能です。
ボックス化
J の配列は高機能ですが、型の制限があるので「数値と文字列の組」のようなものは表現できません。また、ジャグ配列を扱うこともできません。
そこで、どんな値でも格納できる 1 箱 (box) の機能が用意されています。値を箱に入れる (ボックス化する) には、<
(monad) を使います。
a=: <1
a
┌─┐
│1│
└─┘
ボックスは、四角の枠で囲んで表示されます。中に何が入っていても同じボックス型と見なされます。そのため、異なる種類の値の配列を作ることも可能です。
a , <'abc'
┌─┬───┐
│1│abc│
└─┴───┘
上の結果にもあるように、ボックスの配列は四角の枠が連結した形で描かれます。
値を取り出す
ボックスは、そのままでは中身にアクセスできません。
2 + a
|domain error
| 2 +a
値を使うときは、必ずボックスを開けて取り出さなければなりません。暗黙的に変換されることはありません。
値を取り出す verb は、>
(monad) です。
>a
1
2 + >a
3
>2
2
ボックス以外の値に >
を使っても、エラーにはなりません。(そのままの値が返ります。)
ボックスの配列
ボックスの配列は非常によく使われます。
例えば、'abcde'
と 'abc'
という 2 つの文字列で配列を作りたいとします。,:
を使えばできそうな気もしますが、文字列の長さが違うので上手くいきません。
'abcde' ,: 'abc'
abcde
abc
NB. 'abc ' (余分なスペースが 2 つ加わる)
$'abcde' ,: 'abc'
2 5
shape を整えるために末尾にスペースが加えられています。(数値の場合は 0 で埋められます。)
ボックスのリストを使えば、正しく表すことができます。
(<'abcde') , <'abc'
┌─────┬───┐
│abcde│abc│
└─────┴───┘
リストの構築
上の例のように ,
と <
を組み合わせる方法は、リストの要素数が増えると括弧の数も増えて読みにくく なります。
(<'abcde') , (<'abc') , (<'xyz') , <'12345'
代わりに、;
(dyad) を使いましょう。
'abc' ; 1
┌───┬─┐
│abc│1│
└───┴─┘
'abc' ; <1 NB. 右側がボックスでも同じ
┌───┬─┐
│abc│1│
└───┴─┘
'abcde' ; 'abc' ; 'xyz' ; '12345'
┌─────┬───┬───┬─────┐
│abcde│abc│xyz│12345│
└─────┴───┴───┴─────┘
;
は、2 つの値をボックス化して、連結します。
ただし、;
の右の引数がボックス型の場合、左の引数だけがボックス化され、連結されます。それによって、a ; b ; c
のように続けて書くことができます。
リストの展開
a=: 'abcde' ; 'abc' ; 'xyz'
a
┌─────┬───┬───┐
│abcde│abc│xyz│
└─────┴───┴───┘
;a
abcdeabcxyz
;
(monad) は、ボックスのリストから中身を取り出して連結します。配列を作るので、型が合わないとエラーになります。
;'abc' ; 1
|domain error
| ;'abc';1
空のボックス
a:
は空のボックスを表します。
a:
┌┐
││
└┘
「空」のボックスと書きましたが、実際には長さ 0 の配列が中に入っています。
入れ子
J のボックスは、入れ子にすることもできます。
<<1
┌───┐
│┌─┐│
││1││
│└─┘│
└───┘
<<<1
┌─────┐
│┌───┐│
││┌─┐││
│││1│││
││└─┘││
│└───┘│
└─────┘
<'abc' ; 1
┌───────┐
│┌───┬─┐│
││abc│1││
│└───┴─┘│
└───────┘
;
と一緒に使う場合、右の引数の扱いに注意しましょう。
(<1) ; 2
┌───┬─┐
│┌─┐│2│
││1││ │
│└─┘│ │
└───┴─┘
1 ; <2
┌─┬─┐
│1│2│
└─┴─┘
1 ; <<2
┌─┬───┐
│1│┌─┐│
│ ││2││
│ │└─┘│
└─┴───┘
(<1) ; <<2
┌───┬───┐
│┌─┐│┌─┐│
││1│││2││
│└─┘│└─┘│
└───┴───┘
1 ; (2 ; 3) ; 4
┌─┬─────┬─┐
│1│┌─┬─┐│4│
│ ││2│3││ │
│ │└─┴─┘│ │
└─┴─────┴─┘
入れ子のボックスは、木構造を表すのに便利です。
1 ; '+' ; <2 ; '*' ; 3
┌─┬─┬───────┐
│1│+│┌─┬─┬─┐│
│ │ ││2│*│3││
│ │ │└─┴─┴─┘│
└─┴─┴───────┘
J には、構造体のようなデータ型を定義する機能はありません。その代わりに、汎用的なデータ構造として、ボックスが用意されています。
言葉の通り「箱に入れる」「箱から取り出す」といった操作をイメージすると理解しやすいと思います。
[ 前 : 多次元配列 ] [ 目次 ] [ 次 : 様々な数値 ]
-
ここでの「値」は noun のこと。 ↩