【Julia】 基礎: 標準出力

<!-- 【Julia】 基礎 1. 標準出力 -->
# 0. はじめに
Julia を知らない方に向けて記事を書きます．
自分の学習まとめも兼ねています．
目的（モチベーション）は Julia を初めて学ぶ方がどう書いたら良いのか，を提示することです．自分が忘れがちなところを自分で残すという意味でもあります．

Julia は比較的新しい言語であるため，ブログや質問掲示板での（特に日本語での）記述が C/C++ や Python に比べてまだ圧倒的に少ないのです． 

網羅的であることは特に目的ではありません．自分がよく使うところを重点的に書いているためです[^1]．
記事の順番も既知な順に書くわけではありません．加えて自明なことや Python との共通事項は省いてある場合があります．

[^1]: 例えば，この記事では `@printf` や標準入力 `readline()` は扱いません．

Julia の基本文法を，時に Python と比較しながら学んでいきます．最初の記事は同時並行で進みますがそれ以降はその限りではありません．
Python から Julia への学習コストは基本文法についてはほぼ0です．細かな違いはあるので，その都度気をつける必要があります．

## 環境
* MacOS 10.15.4
* Julia 1.8.5
* Python 3.8.6

# 1. `println()`

---

Julia での標準出力は基本的に `println()` 関数が用いられます[^print]．

---

シャープ `#` は1行コメントアウトです．
必要だと思われるところに日本語を書いています．

必要なら Julia でコードを実行してみて下さい．
説明の出力をコメントで書くのは省略しました．

[^print]: [I/O and Network · The Julia Language](https://docs.julialang.org/en/v1/base/io-network/#Base.print) (print の項．直下に println.)

```julia
#%% print.jl
# println が基本．改行で終わる．
println("Hello, world!")# Hello, world!
println("1")# 1
println("1", "2")# 12

println("space は 直接 String で挟む．")
println("1", " ", "2")# 1 2

println("エスケープシーケンス \\n で改行を直接入力")
println("1", "\n", "2")
# 1
# 2
println("2行立てと同じ")
println("1")
println("2")
# 1
# 2
```

一方，Python での標準出力は `print()` 関数を使うのが基本です．出力の自由さと強力さは Python に軍配が上がります．

```python
#%% print.py
# print が基本．改行で終わる．
print("Hello, world!")# Hello, world!
print("1")# 1
# デフォルトで space が挟まれる．
print("1", "2")# 1 2
# 改行で分けたい場合はオプションで指定する．その他違う入力で同じ出力を書くことが可能．
print("1", "2", sep='\n')
# 1
# 2
# end='\n' がデフォルト
print("1")
print("2")
# 1
# 2
```

# 2. `print()`

Julia の `print()` 関数は改行しません (REPL は今考えていません)．使い所を見い出せばとても便利です．

```julia
#%% 
println("Python と異なり print は改行しない")
print("1")
print("2")
# 12
println()# 改行
```

Python で同じことをしたい場合はオプション引数を用いるのがおなじみです．

```python
#%% Python で改行させたくない場合は end=''などとする．sep='' とすると space もなくなる．
print("1", "2", end='', sep='')
# 12
```



# 3. `display()`

---

REPL での配列の標準出力には `display()` を関数を使うのが便利です．

---

しかしREPL と コード実行時で振る舞いが違うので要注意です．Julia コードを実行時に巨大な配列を `display()` させるとすべてプリントしてくるので，このことは避けたほうが良いです．

また `println()` は配列を1行で出力するので時に見にくいです．

配列の要素を一部[^part]または全部[^all]見たいときは `show()` 関数でそれを指定できます．

[^part]: [Julia: limited printing of large arrays - Stack Overflow](https://stackoverflow.com/questions/40788316/julia-limited-printing-of-large-arrays)

[^all]: [Julia: How to pretty print an array? - Stack Overflow](https://stackoverflow.com/questions/62868864/julia-how-to-pretty-print-an-array)

```julia
#%% display()
N = Int(8)
x = rand(N,N)

println("REPL で一部表示，コード実行で全部表示")
display(x) # println(x) は見にくい．
println()


println("REPL でもコード実行でも一部表示")
show(IOContext(stdout, :limit => true), "text/plain", x)# show a part of the output 
println()

println("REPL でもコード実行でも全部表示")
show(stdout, "text/plain", x)# show all the output
println()
```

出力はプログラムを実行すると見られますので，省略します．8行8列のランダム行列です．

対応する Python スクリプトは書きませんが，同じようなことは可能です．


# 4. `@show`


Julia ではマクロ `@show` を使うのも標準的です．
基本1行で出力されます．
重要例を挙げますので他の例は使いながら覚えていきましょう．

```julia
x = 1
@show x
# x = 1
v = [1,0,0]
@show (x,v)
# (x, v) = (1, [1, 0, 0])
@show(x,v)
# x = 1
# v = [1, 0, 0]
```

# 5. `repr()`

Julia で REPL での出力を文字列にしたい時は `repr()` を使いましょう．
これで REPL の結果も TEXT データへ書き込めます．

```julia
a, b = 0, 1
a, b = b, a
repr("text/plain", [a,b])
# "2-element Vector{Int64}:\n 1\n 0"
```

# 6. String interpolation 文字列補間

変数名を使いながら，その変数に格納されている値を文字列型にしてそのまま返す，そんな便利な出力方法があります．それを**String interpolation 文字列補間**といいます[^inter] [^2]．

[^inter]: [Strings · The Julia Language](https://docs.julialang.org/en/v1/manual/strings/#string-interpolation) (Interpolation)

[^2]: [String interpolation - Wikipedia](https://en.wikipedia.org/wiki/String_interpolation#Julia) がよくまとまっています．リンクは Julia の項です．

Julia と Python では以下のように書きます．もしエラーが出て実行できないときは，バージョンを確認してみて下さい．

Julia: 

```julia
#%% interpolation julia
x = 1
println("x = $x")
y = 2
println("x + y = $(x + y)")
# x = 1
# x + y = 3
```

Python:

```python
#%% interpolation python
x = 1
print(f"x = {x}")
y = 2
print(f"x + y = {x + y}")
# x = 1
# x + y = 3
```

ほとんど一緒ですね．Julia を学ぶ喜びが感じられると思います．


# まとめ

Julia の出力の基本をまとめておきましょう．

* `println()` が基本
* `print()` は改行なし
* 配列には `display(), show()` を使う．
* 基本を覚えてきたら `@show, repr()` も使う．
* 文字列補間には `$` または `$()` を使う．


# 参考

1. [I/O and Network · The Julia Language](https://docs.julialang.org/en/v1/base/io-network)
2. [Strings · The Julia Language](https://docs.julialang.org/en/v1/manual/strings/)



<!-- 1. [I/O and Network · The Julia Language](https://docs.julialang.org/en/v1/base/io-network/#Base.print) (print の項．) -->
<!-- 1. [Julia: How to pretty print an array? - Stack Overflow](https://stackoverflow.com/questions/62868864/julia-how-to-pretty-print-an-array) -->
<!-- 1. [Julia: limited printing of large arrays - Stack Overflow](https://stackoverflow.com/questions/40788316/julia-limited-printing-of-large-arrays) -->
<!-- 1. [Strings · The Julia Language](https://docs.julialang.org/en/v1/manual/strings/#string-interpolation) -->