[2019年2月版] Juliaが1.1になっていたので触ってみるか

# Julia 1.1 リリース
発表された当時はまたいいとこ取りの新しいの出てきたな〜ぐらいにしか思っておらず、すっかり忘れていたわけですが気づけば1.0もリリースされておりまして、さらに先日、1.1がリリースされたとのニュースを目にしたのでおおっと！と思い出したわけでございます。

すぐさま本家サイトに飛んで情報を仕入れてきました。

- 本家サイト: https://julialang.org/
- github: https://github.com/JuliaLang/julia
- ドキュメント: https://docs.julialang.org/en/v1/

# さっそく install
対象環境は Mac (macOS High Sierra)です。
以下のサイトからMac用のバイナリをダウンロードしてまいります。

- https://julialang.org/downloads/

例によって ```アプリケーション```フォルダに```Julia-1-1.app```をドラッグ＆ドロップすればインストール完了です。

Finderにて```アプリケーション```から```Julia-1.1.app```をダブルクリックすればREPL用のターミナルが立ち上がります。

```
$ exec '/Applications/Julia-1.1.app/Contents/Resources/julia/bin/julia'
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.1.0 (2019-01-21)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |
julia>
```
はい、JuliaのREPL環境が起動しました。

# Juliaの計算式
Juliaが変態的なのはなんといっても計算式です。それだけじゃないけど言語仕様がてんこ盛りすぎて紹介しきれないのでとりあえず式の書き方からご紹介します。

```julia
julia> 1+1
2

julia> x=5
5

julia> 4x
20

julia> y=4
4

julia> xy
ERROR: UndefVarError: xy not defined

julia> x*y
20

```
数値と変数の乗算で```*```みたいな演算子がいらないってところがミソですね。```4x+1```みたいに学校で習った通りに書けます。
流石に変数と変数の暗黙の乗算はダメです。数値リテラルだけに暗黙の乗算メソッドが定義されてる、と頭にいい聞かせて無理やり納得しましょう。

さらに特徴的な演算は続きます。
算演算子```/```の逆、```\```演算子が登場です。

```sehll
julia> 4 / 5
0.8

julia> 4 \ 5
1.25

julia> 5 \ 4
0.8
```
除単純に「右 割る 左」→「左 割る 右」なのですが、確かに算数の割り算```÷```は「左 割る 右」でプログラマーを長く続けてると"右 分の 左"が当たり前じゃん、と思ってしまいますが、初心の頃は「プログラムって"左 割る 右"じゃなくて"右 割る 左"って書かなきゃいけないんだ！」って思ったような思わないような・・・新鮮だったなぁ。。。
（今でもちょっと考えると"4割る5と5分の4て一緒じゃん？なにが違うの？"って思っちゃいますが、ほら！暗黙で左右入れ替えてるでしょ？っていう〜。訓練の賜物なんだけどね。。。）

さらに配列のeach展開してくれる```.```演算子。

```shell
julia> a = [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> b = [1,0,1]
3-element Array{Int64,1}:
 1
 0
 1

julia> a.*b
3-element Array{Int64,1}:
 1
 0
 3
```
簡単に配列の合成ができてしまいます。。。

あとは超重要なNaNが数値として```==```で比較するのとオブジェクト？として比較する```iseqaul```関数で分けられているので安心。

```shell
julia> NaN == NaN
false

julia> isequal(NaN, NaN)
true

julia> isequal(-0.0, 0.0)
false
```
- ```isequal```は値ではなくオブジェクトのハッシュ値を計算して比較するらしいので、```-0.0```と```0.0.```の区別もします。

そして比較演算子の連結。

```shell
julia> -0.0 == 0.0 == 0 < 1
true
```
- ```0 < f(a) < (b) < 1```のような関数の戻り値も当然、連結して比較できます。
これは便利。

Macで```option+^```と押すと```≠```が出せるんだね！

```shell
julia> 1≠2
true
```

はい、```!=```と同じです。

続いて```option+v```で```√```が出せます。

```shell
julia> .√b
3-element Array{Float64,1}:
 1.0
 0.0
 1.0
```
配列の各要素の平方根求めてますが・・・だんだん、理解が追いつかなくなってきたな。。。w
というか```√配列```だけで呼ぶと以下のエラーが出ます。

```shell
julia> √b
ERROR: MethodError: no method matching sqrt(::Array{Int64,1})
Closest candidates are:
  sqrt(::Float16) at math.jl:1018
  sqrt(::Complex{Float16}) at math.jl:1019
  sqrt(::Missing) at math.jl:1070
  ...
Stacktrace:
 [1] top-level scope at none:0
```
なるほど```sqrt```関数の引数はやっぱり```Flaot16```を受け取るから```b```だけだと```sqrt(Array)```になっちゃってダメなんですね！で、```.```演算子の```each```で```b```を展開するから```sqrt(Float16)```に渡せる、ということですか。あんまりわかりません！w
(```.```が前置でも後置でも動くのが気持ち悪いw)

お次はrational number、有理数です。要は分子と分母が整数の分数です。

```shell
julia> 2 // 3
2//3

julia> 6//8
3//4

julia> g = 90
90

julia> g//5
18//1
```
自動で約数にしてくれます。

虚数も余裕です。

```julia

julia> 1+2im
1 + 2im

julia> 5(1 + 4im)
5 + 20im

julia> r=4; i=3; q=r+i*im
4 + 3im

julia> real(q)
4

julia> imag(q)
3

julia> conj(q)
4 - 3im

julia> abs(q)
5.0

julia> angle(q)
0.6435011087932844

julia> sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
 [2] sqrt at ./math.jl:492 [inlined]
 [3] sqrt(::Int64) at ./math.jl:518
 [4] top-level scope at none:0

julia> sqrt(-1 + 0im)
0.0 + 1.0im
```
俺があんまり余裕じゃないけど。。。```sqrt(-1)```でエラーで、```sqrt(-1 + 0im)```でちゃんと計算してくれるのはさすがです。

配列、行列はプログラマーとしての理解を超えていますw

```julia
julia> a = [ 1 -1-im
       1+im im]
2×2 Array{Complex{Int64},2}:
 1+0im  -1-1im
 1+1im   0+1im

julia> a[1]
1 + 0im

julia> a[1:4]
4-element Array{Complex{Int64},1}:
  1 + 0im
  1 + 1im
 -1 - 1im
  0 + 1im

julia> a'
2×2 LinearAlgebra.Adjoint{Complex{Int64},Array{Complex{Int64},2}}:
  1+0im  1-1im
 -1+1im  0-1im

julia> b = rand(10,10)
10×10 Array{Float64,2}:
 0.276978  0.323021  0.169132  0.195895  …  0.889746   0.926098   0.425271 
 0.798352  0.240408  0.68136   0.167325     0.442709   0.119885   0.353514 
 0.806736  0.847521  0.274664  0.927191     0.519732   0.20163    0.843687 
 0.909628  0.280718  0.262527  0.927031     0.79751    0.852825   0.717645 
 0.859211  0.167855  0.574454  0.929672     0.745732   0.483358   0.820543 
 0.808946  0.323306  0.953342  0.987195  …  0.0455295  0.0437875  0.0437014
 0.965098  0.219585  0.403237  0.8617       0.966326   0.894821   0.365612 
 0.310564  0.231156  0.539079  0.289952     0.95213    0.626799   0.412521 
 0.622888  0.883617  0.219356  0.970493     0.315544   0.913933   0.911824 
 0.326981  0.645471  0.148864  0.246486     0.278956   0.53009    0.740881 
```
要注意なのは配列のインデクスが"1"ベースであるということです。大抵のプログラミング言語は"0"ベースのインデクスですがJuliaは"1"ベースです。
随伴行列ってなんですかね・・・？すいません、実はこっち系全然疎いのですw

# REPLの終わり方
REPLから抜けるには以下のように```exit```メソッドを呼びます。

```julia
julia> exit()
```

# パスを通す。

アプリケーションフォルダにコピーしただけなので当然このままでは```julia```コマンドが他から呼べません。
パスを通します。

```shell
$ vi ~/.bash_profile   # -> export PATH=/Applications/Julia-1.1.app/Contents/Resources/julia/bin:$PATH を追加。
$ source ~/.bash_profile
```
appのバージョンはダウンロードしたバージョンに合わせてください。

# Jupyter で動かしてみる

- [Julia+IJuliaでJupyter Notebookを使うための環境構築 (macOS)](https://qiita.com/ryo-a/items/2f54b960cbcd9f9cd237)

こちらを参考にしつつ以下の手順で Jupyter 用の Julia kernel ```IJulia```をインストールしました。
Anacondaは導入済みとします。

```sehll
julia> using Pkg

julia> Pkg.add("IJulia")
```
インストールが終わったら```notebook```メソッドで起動します。

```sehll
julia> using IJulia

julia> notebook()
install Jupyter via Conda, y/n? [y]: y
[ Info: Downloading miniconda installer ...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 43.3M  100 43.3M    0     0  2799k      0  0:00:15  0:00:15 --:--:-- 3538k
[ Info: Installing miniconda ...

```
あっ。。。おもわず```y```しちゃったけど、Jupyterはinstallしなくてよかったんじゃないかな〜！？

・・・とりあえず起動したのでよしとします。。

jupyterが起動したのを確認したら```control+c```でnotebookのサーバーを停止し、anacondaのnotebookもしくはjupyterlabを起動し、JuliaのアイコンがNotebookとConsoleに追加されているのを確認します。

# VSCode のプラグイン

VS Codeのプラグインはそのものズバリの```Julia```プラグインがあったのでインストールいたしました。
例によって ```hello world```を出力してみます。ついでに引数も表示させてみます。

```julia:sample.jl
println("hello world")

for x in ARGS
    println(x)
end
```
ターミナルを開きsample.jlを実行します。

```shell
$ julia sample.jl 0 aa bbb ccc
hello world
0
aa
bbb
ccc
```

素敵！

続きはJupyterでグラフなどを出してみたいと思います。