> julia 〇〇.jl してはいけないよ[実行方法]

# コード完成!ちゃんと動くかな?　`>julia 〇〇.jl`

　Pythonなどでは割とよくある実行方法ですよね。
　実は、「juliaの実行方法」としては**特殊**な部類なんです。

* 重いパッケージ(Plotsなど)をusingしている。
* 「実行」を短時間に頻繁に行う必要がある(開発中・デバッグ中・頻繁にコード内のパラメータなどを変える必要がある)

などの場合では特に、`julia 〇〇.jl`で実行するのは開発効率の悪化を招くため、**やらないほうが良いでしょう**。また、

* F5で`julia 〇〇.jl`が走る設定
* bashで自動化する際に`julia 〇〇.jl`としている

などの類も(**特別な理由**[^1]がない限りは)**やらないほうが良いです**。

## なぜやらないほうが良いの?
　**遅いから**です。

　juliaの特徴の一つに、「実行速度が早い」というものがあります。しかし、`julia 〇〇.jl`による実行は時間がかかるため、juliaの持ち味が消えます。

## なぜ遅くなるの?
　juliaでは[**JITコンパイラ**](https://ja.wikipedia.org/wiki/%E5%AE%9F%E8%A1%8C%E6%99%82%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9)によるコンパイルが行われるためです。

### JITコンパイラとは?

　**JITコンパイラ**とは、コード内のモジュール、パッケージ、関数などの「ある単位のコード」がまさに実行されるその時(呼び出された際)に、コンパイルしてくれるというものです。

　モジュール、パッケージ、関数などは、1度コンパイルされてしまえば、2回目以降の呼び出しは高速に動いてくれます。

　JITコンパイラで生成された機械語は一時的なものです。実行終了後は無くなります。よって、10回`julia ◯◯.jl`をすれば、コード内の関数は毎回1回ずつ、計10回コンパイルされるということです。

　また、コンパイルはコード内で`using`してあるパッケージにも適用されます。重いパッケージ(Plotsなど)を使っている場合はコンパイルだけで「数十秒」かかってしまいます。

　つまり、一瞬で終了するコードでも、`using Plots`している状態では、`julia 〇〇.jl`をする度に、**数十秒待たなければならない**ということです。デバッグで`julia 〇〇.jl`する人々からしてみれば、juliaは「使い勝手の悪い言語」に見えてしまうでしょう。


### 欠陥言語だ! Pythonのほうがマシ!

　昔筆者はそう思いました。皆さんはどう思ったでしょうか。でも実はそんなことはありません。想定された使い方をしていないために不便になっているのです。juliaで`julia 〇〇.jl`するのは、自転車を担いで走るようなものです。自転車は乗りましょう。Juliaには`julia 〇〇.jl`より理にかなった実行方法があるのです。
　
### なんか面倒そうな使い方だな

　使い方はちょっとしか変わりません。新たに覚えることも少ないです。それに、うまく使いこなせば**pythonより早い実行時間**かつ**C++よりも早いコンパイル時間**で開発が出来ます。慣れてしまったら最後、**他の言語に後戻りは出来ない**かも...しれません。

## 具体的には?
　「理にかなった実行方法」は色々あります。いくつか軽く紹介していきます。

### REPLを使う
　@mametankさんに教えていただきました。一番簡易で、「`julia 〇〇.jl`の代わりの行動」として考えると、一番自然な手段です。

* コンソールを立ち上げ、`julia`と入力し、juliaのREPLを立ち上げます。
* `include("〇〇.jlのパス")`と入力すると実行されます。
* 〇〇.jlを修正して実行したい場合は、REPLを立ち上げたまま修正します。
* 修正後の再実行は、`include("〇〇.jlのパス")`と入力することで行えます。

　以上です。「コンソール上で`julia 〇〇.jl`」という行為が、「juliaのREPL上で`include("〇〇.jl")`」に置き換わっただけです。再実行時はREPL上にデータが保持されているため、高速に実行されます。

### jupyterを使う
　「jupyter + IJulia」を用いることで、アドホックなコードを「書き捨てる」ようにプログラミングすることも出来ますし、**Markdown**形式でメモを残すことで「**説明**付き・**数式**付きのプログラム」を書くことができます。
　「アカデミックな環境」と相性が**良い**です。「講義資料」や、「実験ノート」代わりにもなります。
　普通のコーディングスタイルとは結構異なってくるため、好き嫌いが分かれます。
　筆者はどうしてもぐちゃぐちゃになってしまうため、あまり使っていません。

> 参考:[これ](https://qiita.com/msekino/items/dbfe11ad05f20fd3efd3)とか、[これ(情報が古いかもしれません)](https://genkuroki.github.io/documents/Jupyter/20170615InstallJuliaAnaconda.html)


### Atom + Junoを使う
　詳しくないので**割愛**しますが、「インターフェース」が優れており、「なかなか**便利**」らしいです。

> 参考:　[これ(先ほどと同リンク)](https://qiita.com/msekino/items/dbfe11ad05f20fd3efd3)とか、[これ](https://qiita.com/SatoshiTerasaki/items/3dda33ece801b75e248c)

### VSCodeを使う
　筆者が主に使っている方法です。基本は「普通にVSCodeを使うだけ」なので、普段からVSCodeを使っている方に**おすすめ**です。準備としては、

* juliaを入れる
* VSCodeを入れる
* VSCodeにjulia拡張を入れる(extension検索ウィンドでjuliaと入力して出てくる一番上)。

です。

　実行方法ですが、私の環境(Ubuntu18.04 LTS)の場合、「Shift+Enter」です。REPLが開き、開いているコードを実行してくれます。実行後もコンパイルデータがREPL上に保持されているため、2回目以降の実行(Shift+Enter)では「コンパイルなし」で実行のみ行われます。

　「コードに修正を加えてから再実行」する際も「Shift+Enter」で「変更箇所のみコンパイル+実行」をしてくれます。

　「Ctrl+Enter」で一行ずつ読み込ませることができますが、使いどころがわかりません。
　また、windowsでは素の状態だとキー割当が無かった・違ったような気がします。julia extensionのオプションとか、ショートカットキーの一覧などから探してみてください。

> 参考:　みつからないぜ☆

### コンパイルしちゃう
　PackageCompiler.jlを用いると〇〇.jlをプリコンパイルして「共有ライブラリ」に出来ます。クリティカルに高速化が必要な場合や、共有ライブラリを作りたい場合などに使えるのでしょうか。しかし「可搬性や柔軟性」を考えると**イマイチ**なので、まず最初に上記の方法を試してみて、それでも納得行かなかった場合の**最終手段**という雰囲気です。クロスコンパイルが出来るようなら、個人的に気になります。情報求む。

~~もはやC++とかFortranでよくね?~~

> 参考:　[これ](http://p1sces.hatenablog.com/entry/JuliaAdventCalendar2018-18)



---

　筆者が知っている方法はこんなものです。(図に乗って知らない方法も紹介しました。)
　どの方法においても、「実行後も、**コンパイルされた関数をREPLなどで保持**するようにしておいて、コードを書き換えた後の再実行時は、**書き換えられた関数**だけが再コンパイルされる」という環境となっています。それさえ守られていれば、あとは各々工夫していけば良いと思います。

　個人的にREPLって、pythonでは「導入部分でちょっと触れるだけのイマイチ使いどころがわからないヤツ」という認識だっただけに、juliaでこんな主役級の機能になっているとはちょっと驚きました。

　その他、筆者は経験がないですが、**大規模開発、テスト、gitとの連携、環境管理**などを快適に行うための使い勝手の良いパッケージなどがいくつかあるようです。これらを使いこなせると幸せになれるかも知れません。

> 参考:　[これ](https://qiita.com/mametank/items/43330a9452f0039ca22d)とか、[これ](https://myenigma.hatenablog.com/entry/2018/08/11/134708)など。



## まとめ
　juliaは色々とクセがある言語ですが、juliaに入ってはjuliaに従って書くことで、「**自然**に高速・省メモリ・柔軟なコードが書ける」という強力な**魅力**があります。juliaの「入門記事」や「高速化の記事」は最近増えてきていますが、肝心の**実行方法**について、詳しく説明している記事は少ないようです。`julia ◯◯.jl`のような罠もあるため、今回は「juliaの実行方法」についての話を書いてみました。「読者像」をはっきり決めずに執筆したので、「くどくどしてたり雑だったり」という記事になってしまったかもしれません。

　なにかあればコメントお願いします。筆者も勉強中のため、より良い方法があれば教えていただけると幸いです。ここまで見てくださった方々ありがとうございました。

[^1]: **特別な理由**: 実は「`julia 〇〇.jl`しても良い」場合があって、「実行時間がとても長い」場合(jobを投げてほっとく系)です。例えば、「実行に丸2日かかるコード」などは、コンパイルに1分かかったとしてもトータルに占めるコンパイル時間は微々たるものです。このような場合は「実行結果を既存のC++コードで解析をしたいなあ」などの要請によって、「スクリプトの中で`julia 〇〇.jl`によってjuliaを動かす」みたいな場面も出てくると思います。そのような**特別な理由**がある場合においては、**自然な実行方法**と言えるでしょう。