J言語 基礎最速マスター
Project Eulerなどで妙に人気がある言語で前々から気になっていたので,勉強がてら書いてみる.
まだ誰も書いてないみたいだし.
他の言語については(基礎|変態)文法最速マスターシリーズのまととかを見てください.
※初心者なので間違え注意.指摘をお願いします.
J言語はAPLの後継で配列処理の強力な言語.
ASCIIコードの1,2文字で膨大な演算子が定義されている上,
前置記法と後置記法で意味が異なるため可読性に乏しいが複雑な演算を短く書ける.
ジョーク言語ではないが,属性は3(書けるし実行できるが読めない)
基本事項
print文
quoteで囲む
'Hello World!'
コメント文
NB. の後に書く.
'Hello World!' NB. comment
数値
基本事項
- _ (後に数を書いた場合)負号
- _ (単独で)無限大
- __ 負の無限大
- e 指数
1e3 1000
- (分子)r(分母) 有理数
2r3 NB. 2/3 2r3
- (実部)j(虚部) 複素数
1j2 NB. 1+2i 1j2
四則演算
演算子は2項演算子の場合と単項演算子の場合で意味が異なる.
(演算子のことをJ言語では動詞というみたいですが,あえて無視する.)
二項演算としての場合
- + 足し算
1+1
- - 引き算
3-1 2 2-3 _1
- * 掛け算
2*3 6
- % 割り算(スラッシュでないことに注意)
6%2 3 2%3 0.666667
演算子はすべて右結合であることに注意
1%1+1 0.5
単項演算子としては次のようになります
- + 複素共役
+ 1 1 + 1j1 1j_1
- - 負号反転
- 2 _2 - _2 2 - 2j3 _2j_3
- * 符号(絶対値を1にする)
*2 1 *_3 _1 *0 0 *3j4 0.6j0.8
- % 逆数
%2 0.5
真偽値
1で真,0で偽を表す.
演算
- +. or
- *. and
- +: nor
- *: nand
- -. not
比較
二項演算として
- = 等号
- < 小なり
- > 大なり
- >: 大なりイコール
0 = 0 1 'a' = 'a' 1 2 < 3 1 2 < 2 0 2 <: 2 1 0 = '0' 0
配列
空白区切りで数字を並べると配列になる.
1 2 3 1 2 3
配列演算
- # (単項演算子として)配列の長さを求める
# 1 1 1 3
- {. head
{. 1 2 3 1
- {: last
{: 1 2 3 3
- }. tail
}. 1 2 3 2 3
- }: init
}: 1 2 3 1 2
- { (2項演算子として)配列のi番目の要素を取り出す(0オリジン)
0 { 1 2 3 1 1 { 1 2 3 2 3 { 1 2 3 |index error | 3 {1 2 3 0 1 0 { 1 2 3 1 2 1
- } 配列のi番目の要素をkにする
2 (3}) 1 1 1 1 1 1 1 1 1 2 1 1 2 (1 3}) 1 1 1 1 1 1 1 2 1 2 1 1 2 4 (1 3}) 1 1 1 1 1 1 1 2 1 4 1 1
- , 配列の結合
1 2 3 , 4 5 6 1 2 3 4 5 6
- 要素数がおなじ配列を二項演算でつなぐと,対応する要素同士に演算を施した配列が返ってくる.
(HaskellでいうzipWithみたいなもの)
1 2 3 + 4 5 6 5 7 9
1 + 1 2 3 2 3 4
- 単項演算を配列に作用させると,配列の各要素に作用される
- 1 2 3 _1 _2 _3
+ / 1 2 3 6
- i.n 0からn-1までの整数の配列を作る
i.10 0 1 2 3 4 5 6 7 8 9
- テーブル(行列)をつくる
2 2 2 $ i.8 0 1 2 3 4 5 6 7
こうも書ける
i. 2 2 2 0 1 2 3 4 5 6 7
演算子の合成
演算子を続けて書いたとき,演算順序が特殊になる.
部分適用,単純な合成
m&v yはm v yであることを利用する
(^&3) i.10 NB. 各要素の3乗
0 1 8 27 64 125 216 343 512 729
(>&4) i.10 NB. 各要素は4より大きいか
0 0 0 0 0 1 1 1 1 1
( (*&2) & (^&2) ) i.10 NB. 各要素を2乗して2倍
0 2 8 18 32 50 72 98 128 162
フック
x,yを引数, f,gを演算子とするとき,
(f g) y => y f (g y)
x (f g) y => x f (g y)
のように計算される.
(- -) 1 NB. 1 - (-1)=2 2 2 (* *) 3 NB. 2 * (*3) = 2 * 1 = 2 2
フォーク
x,yを引数,f,g,hを演算子とするとき,
(f g h) y => (f y) g (h y)
x (f g h) y => (x f y) g (x h y)
のように計算される.
(+/ % #) 2 4 9 NB. (+/ % #) 2 4 9 = (+/ 2 4 9) % (# 2 4 9) = 15 % 3 = 5 (つまり平均) 5
トレイン
e f g h は (e (f g h)) の意味((f g h)のフォークとeをフック)
以下同様に
(a_1 a_2 a_3 ... a_{2n}) => フック (a_1 (a_2 a_3 ... a_{2n}))
(a_1 a_2 a_3 ... a_{2n-1}) => フォーク (a_1 a_2 (a_3 ... a_{2n-1}))
変数,演算子定義
=.で局所定義,=:で大域定義する.
変数
=.や=:を使うだけ.
num =: 1 num+1 2 num=:num+1 num 2 a,(a=.1 2 3) 1 2 3 1 2 3
制御構文
この辺を使うとJっぽくないような気がする.
if文
Tブロックにはブールが来る(0でないなら真)
- if文
if. T do. B end.
- if 〜 else 文
if. T do. B1 else. B2 end.
- if 〜 elseif文
if. T do. B1 elseif. T1 do. B2 elseif. T2 do. B3 end.
- 例:階乗
fact =: 3 : 0 if. y<1 do. 1 else. y*(fact (y-1)) end. ) fact 3 6 fact 4 24
for文
Tブロックの各要素についてBブロックが評価される.
- インデックスなし
for. T do. B end.
- インデックスj
for_j. i.y do. B end.
- 例:1からyまでの和
sum =: 3 : 0 s=.0 for_j. i.y do. s=.s+j+1 end. )
continue, break, return
普通に使える.
具体例
1000以下の3か5で割りきれる数の和
まずは,適当に
+/(*((0&=)&(5&|)+.((0&=)&(3&|)))) i.1000 233168
(0&=)&(3&|)が3で割り切れるか,
(0&=)&(5&|)が5で割りきれるかを表す.
+.はブールとしてのor
これらをフォークで合成し,3か5で割りきれるか
+/で和をとる.
少し短くしてみる
+/((*=&0)5&|*3&|)i.1000
4両列車
参考文献
まだまだ紹介しきれなかった機能はたくさんあります.
さらなる情報を欲しい方は下の文献を参考に.
- J言語基礎講座 日本語でまとまってる資料
- Jsoftware J言語の総本山
- J Primer Jの入門書
- Dictionary 辞書
- User Manual
- Wikipedia