明示的定義の例
ファイルに関数定義を 書くときは関数名に=:を用いなければならない。
grobal定義は 関数の枠を超えるので定義名が衝突すると後者優先になる。
しかし、明示的定義のデバックに便利で、最後にlocalに戻しておくとよい
mean=.'(+/y)%#y' 3 : mean 3 : '(+/y)%#y' 13 : mean +/ % #他の品詞についても、それぞれに呼応して10~12にコロンを付して変換できる。 (ただし変換が可能な場合に限る。)
Jはリリ-ス2から制御構文を採用した。制御構文は、明示的定義で 利用できる。
制御構文は他の言語とあまり変わらない。
for_abc は for_ctr のようにして用いるとcounter文が省略できる。
Aが「0」でない(真の)ときB1を実行し、Aが「0」でC1が「0」でないときに B2を実行し、さらにC1が「0」でC2も「0」のときB3を実行する。
zero=: 3 : 0 if. 0=y do. 'zero' else. 'nonzero' end. )
zero 3 nonzero zero 0 zero
pzm=: 3 : 0 if. y=0 do.":0 elseif. y>0 do.":1 elseif. y<0 do.":_1 end. )
pzm (L:0) 3 ; 0 ; _3 +-+-+--+ |1|0|_1| +-+-+--+
Aが「0」でない(真である)限りBを実行する。
まずBを実行し、Aが「0」でない(真である)限りBを実行する。
fact=:3 : 0 f=.n=.1+y while. n>1 do. f=.f*n=.n-1 end. )
fact ("0) i.5 1 2 6 24 120 !i.6 1 1 2 6 24 120
box=:3 : 0 b=.'' [ n=.>:y whilst. n>1 do. b=.b, box 4 +-+---+-----+-------+ |0|0 1|0 1 2|0 1 2 3| +-+---+-----+-------+for
- try. B1 catch. B2 end.
B1を実行し、エラーがあればB2を実行する。
- for. B1 do.B2 end.
「B1」の回数だけ「B2」を実行する。
sum=:3 : 0 try. +/1+i.0>.y catch.'miss!' end. ) sum 10 55 sum 'a' miss!fact1=:3 : 0 f=.n=.((]>:0:)*1:>.|)y for.i.<:n do. f=.f*n=.<:n end. )fact1 ("0) i.6 1 1 2 6 24 120iota=:3 : 0 s=.0:`$@.(]=0:) y for_j. i.|y do. if.j=0 do. continue. end. s=.s,j end. |.^:(_1=*y)s )iota 5 0 1 2 3 4 iota _5 4 3 2 1 0 iota 0select.
select.Y
case. 0 do.D1
case. 1 do.D2
case. 2 do.D3
end.
「Y=1,2,3」に呼応して「D1,D2,D3」を実行する。
- 【さらに、次のような制御命令も用意されている】
- break.
while(whilst) 構文から抜け出す。- continue.
while(whilst) 構文を続ける。- goto_name. ラベル名
label_xyz(name) へジャンプする。- label_name.
goto のジャンプ先- return. 構文の流れから抜け出す。
case=:3 : 0 select. y case. 0 do. i.1 case. 1 do.i.2 fcase.2 do.i.3 end. )case (L:0) {@> >:i.3 +-+---+-----+ |0|0 1|0 1 2| +-+---+-----+ L:0による並列演算csum=: 3 : 0 for_ctr. i. # y do. 1!:2&2 tmp=. ctr{y end. )- for_xyz
xyzに任意の文字を入れてカウンターに用いる
(i,j)はJでは至る所に用いられているので注意
test_forabc=: 3 : 0 A=: 10+i.10 ANS=. 0 for_ctr. i. 10 do. ANS=. ANS+tmp=. ctr{A end. ANS ) test_forabc '' 145再帰
再帰のprimitive($:) が復活したようだ。その使用法と最近出来た M.(Memo) と合わせて効果を計測する。 \[ ! 3 \rightarrow 3 \times 2 \times 1 \rightarrow 6 \] Jの階乗のprimitiveは(!)であり、良く錬成されていて早い。! i.10 1 1 2 6 24 120 720 5040 40320 362880 ts '! i.10' 6.05313e_6 896ここでは再帰の学習のため再帰を用いた3様の階乗を用いる。ScriptはChris.Burk and Cliff Reiterによる
- 明示型で記述
fac1=: 3 : 0 if. y<:1 do. 1 else. y * fac1 y-1 end. )- 関数型の再帰。
fac2=: 1: `(*fac2@<:)@.*- 再帰の\it{primitive}($:)を用いる。
fac3=: 1:`(*$:@<:)@.*- また実行速度と\it{Memo M.}の有効性も計測する
fac10=: fac1 M. fac20=: fac2 M. fac30=: fac3 M.- [timer] 外部接続詞を用いて実行速度と使用spaceを計測する ts=: (6!:2),7!:2
- [各scriptと計算結果]
fac1 "0 i.10 1 1 2 6 24 120 720 5040 40320 362880 fac2 "0] i.10 1 1 2 6 24 120 720 5040 40320 362880 fac3 "0] i.10 1 1 2 6 24 120 720 5040 40320 362880- [計測結果]
- fac1 M.の方が幾分早い
ts 'fac1 "(0) i.100' 0.0394941 148288 ts 'fac10 "(0) i.100' 0.0352531 130944- fac2。fac1より高速
ts 'fac2 "(0) i.100' 0.0139541 46464 ts 'fac20 "(0) i.100' 0.0137531 48320- fac3はfac2より早い。M.の効果はない。Tuningが進むとM.の効果は 相殺されるようだ。
ts 'fac3 "(0) i.100' 0.00592404 46272 ts 'fac30 "(0) i.100' 0.00655782 48320関数型の再帰スクリプトは難解であり、単独の科学技術計算やprogram ,logicの学習に限定した方が無難である。
Mapped fileJには更に直接メモリ周りを扱うMapped fileの機能がある。 詳細はLABのtutorial参照