Julia独習メモ ＜1＞

Juliaに入門した。そのときのメモをここに書く。n日目表記は、実際の日数とゆるく対応している。
あまり、誰かの役に立つのかは分からないが、メモ書きとして公開する。

# 1日目　環境構築
[juliaup](https://github.com/JuliaLang/juliaup#installation) をインストールすることで、Julia自体もインストールできた。
VSCodeのJulia拡張をインストールした。初回はLSPの立ち上げに時間がかかった。

# 2日目 マニュアルを読み始める
私は、比較的多くのプログラミング言語を既に知っている人間なので、[マニュアル](https://docs.julialang.org/en/v1/manual/getting-started/)をてっぺんから読んでいくスタイルで学ぶ。
この方法は、あまり慣れていない者にはおすすめしない。

## [Getting Started](https://docs.julialang.org/en/v1/manual/getting-started/)
インタラクティブセッション(REPL)の立ち上げと説明。REPLにおいては、変数`ans`が、直前の評価結果を保持する。
`include("file.jl")`でファイルを読み込んで評価できる。(REPL内でこれを行うと、外部ファイルの`ans`を読み込めた)

REPLを立ち上げずにファイルを動作させるときは `julia script.jl` のようにやる。

REPLで `?` をタイプするとヘルプモードになって、調べたいことが調べられる、という便利情報。

## [Variables](https://docs.julialang.org/en/v1/manual/variables/)
変数は宣言とかは特に行わない。`x = 10`のようにすることで、変数が値に束縛される。
Unicodeの変数名にも対応している。

```jl
力💪 = "POWER"
```

REPLでは、LaTeX記法のように、`\delta`-tabのように打つと、$\delta$になる、などの機能がある。
人からもらったコードで読み方が分からないものは、REPLのヘルプモード(`?`)で調べられる。

```jl
help?> 力💪
"力💪" can be typed by 力\:muscle:<tab>

help?> α̂⁽²⁾
"α̂⁽²⁾" can be typed by \alpha<tab>\hat<tab>\^(2)<tab>
```

`pi`や`sqrt`のようなbuilt-inの定数や関数は、使われる前であれば書き換えることができる(非推奨)が、一度使われてから書き換えるとエラーが発生する。

[使うことができる変数名](https://docs.julialang.org/en/v1/manual/variables/#man-allowed-variable-names)については、とてもめんどくさいことが書かれているので、気になったとき再度参照する。
先頭1文字はアルファベットかアンダースコアか、とても雑に言うと非ASCIIなUnicode文字。以降は、それに加えて、数字や`!`が使える。

演算子を定義することもできて、例えば `+ᵃ` を定義した場合、 `+ᵃx` は `+ᵃ` `x` なのか `+ ᵃx` なのか区別できるよう前者で書かなければならない。

アンダースコアのみからなる変数(`_`, `__`, `___`, ...)は扱いが特殊で、代入後、即時に破棄されるので、参照することはできない。

[キーワード](https://docs.julialang.org/en/v1/base/base/#Keywords)は変数名にできない。

UnicodeはJulia上では、NFC正規化 + 一部独自の正規化によって扱われる。

`a[1] = 42`のようなものは、実は代入じゃないことが書かれている(Pythonとかもそうだよね)

### Stylistic Conventions
以下が推奨される。

- 変数名は小文字
- 単語の区切りは`_`で示してもよいが、区切らないと読みづらい場合を除いては推奨されない
- 型とモジュールの名前は大文字で始まり、単語の区切りはCamelCaseにより表す
- 引数に書き込みを行う関数("mutating"あるいは"in-place"な関数)の名前の末尾には`!`をつける

## [Integers and Floating-Point Numbers](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/)
型の名前が `UInt32` などの名称で定義されている。

### 整数
型名が指定されていない場合の整数リテラルは、32ビットシステムでは`Int32`, 64ビットシステムでは`Int64`になる。ただし、32ビットで表せない整数リテラルは`Int64`になる。
64ビットで表せない整数リテラルは`Int128`、それでも表せない整数リテラルは`BigInt`になることを確認した。

整数型の最小値・最大値は、`typemin`, `typemax`で取れる。

```jl
julia> typemin(Int64), typemax(Int64)
(-9223372036854775808, 9223372036854775807)
```

あまり驚くべきことではないが、以下のような挙動を示す。

```jl
julia> 9223372036854775808 + 9223372036854775807
18446744073709551615

julia> typeof(ans)
Int128

julia> 9223372036854775807 + 9223372036854775807
-2

julia> typeof(ans)
Int64
```

任意精度の整数型である`BigInt`は`big(1)`や`big"1"`のように作ることができる。
他の整数型は`Int16(1)`のように作ることができる。

整数の除算は `div(3, 2)` または `3 ÷ 2` のように行う(`3 / 2`では浮動小数点型を返す。`÷` は `\div`-tabで入力する)。
ゼロで割ったときおよび、整数型の最小値(`typemin`で得られる値)を`-1`で割ったときは、`DivideError`が投げられる。
余りは `rem` または `%` で求める。

### 浮動小数点数
リテラルは通常は`Float64`として扱われる。
`Float32(1.5)`のようにするか、または、 `1e10` のような表記の`e`を`f`にすることで`Float32`が得られる。

半精度浮動小数点数もサポートしている。 `Float16(1.5)`

`Float64`では、16進リテラル記述も行うことができる。(`0x`はじまりで、`e`を`p`にする)

```jl
julia> 0x1p0
1.0

# 16進小数点第1位は、(1/16)の重みを持つ。
julia> 0x0.1p0
0.0625

julia> 0x0.2p0
0.125

julia> 0x0.4p0
0.25

julia> 0x0.8p0
0.5

julia> 0x0.cp0
0.75

julia> 0x0.fp0
0.9375


# 16進小数点第2位は、(1/16^2)の重みを持つ。
julia> 0x0.01p0
0.00390625

julia> 1.0 / 16^2
0.00390625

# 16進小数点の指数表記(p以降)の重みは2
julia> 0x1p0
1.0

julia> 0x1p1
2.0

julia> 0x1p2
4.0

julia> 0x1p-1
0.5

julia> 0x1p10
1024.0
```

`_` は整数リテラルまたは浮動小数点数リテラルで、セパレータとして使用できる(読みやすくするために使用でき、無視される)

`bitstring`関数で、バイナリ表記を見ることができる。

```jl
julia> bitstring(0.5)
"0011111111100000000000000000000000000000000000000000000000000000"
```

`Inf`, `-Inf`, `NaN` が`Float64`に、`Inf32`, `-Inf32`, `NaN32`が`Float32`に、同様のものが`Float16`に定義されている。

`typemin, typemax`は、以下の値を返す。

```jl
julia> (typemin(Float16),typemax(Float16))
(-Inf16, Inf16)

julia> (typemin(Float32),typemax(Float32))
(-Inf32, Inf32)

julia> (typemin(Float64),typemax(Float64))
(-Inf, Inf)
```

マシンイプシロンは`eps`で得られる。 `eps()`は`eps(Float64)`と同じ。
`eps`の引数は値を指定することもでき、`eps(x)`で、`x < x + eps(x)`となるような値が得られる。

`nextfloat`, `prevfloat`によって、次/前の値を得ることができる。

### 定数係数
以下のような記法が可能

```jl
julia> x = 3
3

julia> 2x^2 - 3x + 1
10

julia> 1.5x^2 - .5x + 1
13.0

julia> 2^2x
64

julia> 2(x-1)^2 - 3(x-1) + 1
3

julia> 2π
6.283185307179586
```

以下のようには書けない。

```jl
julia> (x-1)(x+1)
ERROR: MethodError: objects of type Int64 are not callable

julia> x(x+1)
ERROR: MethodError: objects of type Int64 are not callable
```

`0xff`は、`0 * xff`とは解釈されない。(`0x`, `0o`, `0b`から始まる場合は、常に、16進, 8進, 2進リテラルとして扱われる)
`1e10` も同様に、 `1 * e10`とは解釈されない。`E`や`f`も同様。
しかし、`F`はそのような特別扱いがされない。(`1F10`は`1 * F10`)

### 0と1
`zero(Float32)`や`zero(1.0)`のようにしてゼロを作ることができる。同様に`one`を使って1を作ることができる。