Julia/Control Flow
Compound Expressions
Scalaでいうところのブロック式、Schemeでいうところのbeginがある
code:jl
julia> z = begin
x = 0
x += 1
x += 1
x
end
2
beginのかわりに、()でくくって;で分離する記法がある
code:jl
julia> z = (x = 0; x += 1; x += 1; x)
2
Conditional Evaluation
おなじみifとかですな
Juliaではif .. elseif .. else .. end形式
windymelt.icon thenはないんすね
条件節の後に改行しないといけないな〜と思ったけど普通にできた
code:jl
julia> if 42 ÷ 2 == 21 777 else 666 end
777
ifブロックはローカルスコープを形成しない
i.e. スコープ内で定義したものはifを抜けても使える
やや奇異だな・・・
code:jl
julia> if 32 ÷ 2 == 16
x = "ok!"
end
"ok!"
julia> x
"ok!"
実用的な観点からすると、最初に空の変数を置いとく、みたいなテクが不要になる
code:ts
let x = "";
if (32 / 2 == 16) {
x = "ok!"
}
ifは式なので値を返せる
Scalaやってた身からすると普通にありがたい
ifはtrueかfalse以外を許容しない
code:jl
julia> if 0 0 else 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context
Stacktrace:
三項演算子がある
x ? y : z
Short-Circuit Evaluation
LLではおなじみ、&& や || が使える
code:jl
julia> false || println("evaluated")
evaluated
julia> true || println("evaluated")
true
左辺側にはbooleanしか使えない
このため連鎖はできない
Repeated Evaluation: Loops
whileとforがループのプリミティブとして用意される
while
code:jl
julia> n = 10
10
julia> while (n -= 1) > 0
println(n)
end
9
8
7
6
5
4
3
2
1
ループはスコープを形成するので、外の値をいじるにはglobalと書く
code:jl
julia> i = 1;
julia> while i <= 3
println(i)
global i += 1
end
1
2
3
for
code:jl
julia> for n = 1:10
println(n)
end
1
2
3
4
5
6
7
8
9
10
配列でもよい
行列でもよい(!?)
カラムが先に処理される
code:jl
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> for n = m
println(n)
end
1
4
2
5
3
6
=のかわりにinとか∈(\in<TAB>)を使ってよい
可読性が上がる
whileもforもスコープを形成するため、ループ変数は外部からは見えない
for outerというのもあるそうだが後で
他言語同様に、breakもcontinueもある
code:jl
julia> for n ∈ 1:50
n % 15 == 0 && (println("fizzbuzz"); continue)
n % 3 == 0 && (println("fizz"); continue)
n % 5 == 0 && (println("buzz"); continue)
println(n)
end
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
...
多重forもできる
code:jl
julia> for i ∈ 1:9, j ∈ 1:9
println("$i × $j = $(i*j)")
end
1 × 1 = 1
1 × 2 = 2
1 × 3 = 3
1 × 4 = 4
1 × 5 = 5
1 × 6 = 6
1 × 7 = 7
1 × 8 = 8
1 × 9 = 9
2 × 1 = 2
2 × 2 = 4
2 × 3 = 6
...
カンマで区切ることで多重化する
カッコはつけてはいけない
多重forでのbreakやcontinueは全体に対して適用される
Exception Handling
Juliaには例外機構がある
throw()する
code:jl
julia> throw(DomainError("boom"))
ERROR: DomainError with boom:
Stacktrace:
Errors
error("message")するとErrorExceptionが発出される
ErrorExceptionはもっとも一般的な例外
try/catch
code:jl
julia> try
error("boom!")
catch e
println("error occurred: $e")
end
error occurred: ErrorException("boom!")
catchしたらisaを使って分岐する
catchしてからelseを呼べる
code:jl
julia> try
# error("boom!")
catch e
println("error occurred: $e")
else
println("else clause is called")
end
else clause is called
tryが通過して例外が起きなかった場合にのみ呼ばれる
tryもスコープを切るのでtry中の変数は呼べないぞ
finallyがある