はじめに
JuliaはMITで開発された言語で、2009年に誕生し、2012年に公表されました。開発者はブログ(訳はこちらから引用)で
我々は、オープンソースでリベラルなライセンスの言語がほしい。C言語の速度と、Rubyのダイナミズムがほしい。同図像性があり、LISPのような真のマクロを備えつつ、Matlabのように分かりやすくなじみのある数学的記法を使える言語がほしい。汎用的なプログラミングはPython並みに便利で、統計の扱いはR言語並みに容易で、文字列処理はPerl並みに自然で、線形代数はMatlab並みに強力で、プログラムの連結はシェル並みに得意な言語がほしい。習得が超簡単でありながら、筋金入りのハッカーが喜んで使い続ける言語がほしい。インタラクティブでありつつ、コンパイル方式の言語がほしい
と言っています。最高にクールですよね。
そんなJuliaは日本語の書籍や記事がPythonに比べると非常に少ない・・のですが、つい先日「1から始めるJuliaプログラミング」という書籍が出ました!
やはり書籍にまとまっている、というのは大変助かります。
本記事ではそんなJuliaのWindowsでの開発環境構築について書きます。
Juliaのインストール
Juliaの公式サイトからインストーラーをダウンロードしてインストールしてください。
環境変数の設定
- インストールしたJuliaのbinへのパスを JULIA_HOME などとして、Pathに %JULIA_HOME% を追加します。
- パッケージを開発する際、デフォルトでは ~/.julia/dev に作成されます。パスを変えたい場合は JULIA_PKG_DEVDIR を設定します。
Jupyter Lab
実行時のコードや実行結果を残しながら開発していくのに、Jupyterは非常に便利です。そんなJupyter公式の「I Python, You R, We Julia」という記事には
The name is also a play on the languages Julia, Python, and R
とあり、JuliaはJupyterの名前の由来にもなっています。是非入れておきたいところ。
Anacondaなどでインストールできます。Anaconda Promptで
(base) C:\Users\(ユーザー名)> jupyter lab
で立ち上げます。
なんということでしょう・・・名前の由来にもなっているというのに、デフォルトではJuliaは入っていません。
Jupyter LabにJuliaを追加する
コマンドプロンプトかAnacondaプロンプトで、 julia と打つとJuliaのREPL(read-eval-print-loop)が立ち上がります。
(base) C:\Users\(ユーザー名)> julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.4.0 (2020-03-21)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia>
REPLには5つのモードがあります。
-
Juliaモード
- Juliaのコードを実行するデフォルトのモード
-
パッケージモード
- ] キーで起動
- パッケージのインストールや依存関係を管理するモード
-
ヘルプモード
- ? キーで起動
- 関数やマクロのドキュメントを確認できます。
-
シェルモード
- ; キーで起動
- シェルのコマンドを実行するモード
-
サーチモード
- Ctrl+r で起動
- コマンドの履歴を検索できます。
] キーを押してパッケージモードに入りましょう。パッケージモードで
(@v1.4) pkg> add IJulia
でIJuliaがインストールされます。再度Jupyter Labを立ち上げると、Juliaが使えるようになっているかと思います。
PkgTemplatesとReviseをインストールする
PkgTemplates
PkgTemplatesはパッケージの雛形を作ってくれます。 ] キーを押してパッケージモードに入り
(@v1.4) pkg> add PkgTemplates
でインストールされます。BackspaceでJuliaモードに戻り、
julia> using PkgTemplates
julia> t = Template(user="(ユーザー名)")
などとすると、パッケージの雛形が作成されます。試しに Example というパッケージを作成してみましょう。
julia> t("Example")
JULIA_PKG_DEVDIR に設定したパス(設定していない場合は ~/.julia/dev)にExampleフォルダができます。
Exampleフォルダにはパッケージに必要なファイルが一通り作られます。
- .git/
- src/Example.jl
- test/runtests.jl
- LICENCE
- Manifest.toml
- Project.toml
- README.md
Project.toml や Manifest.toml にはそのパッケージの情報や、依存するパッケージが記載されます。Manifest.tomlは直接編集する必要はありません。開発パッケージへの依存パッケージの追加方法は後述します。
(@v1.4) pkg> status
とすると、その環境にインストールされているパッケージの一覧を確認できます。Example v0.1.0 が追加されていることを確認しましょう。
Revise
パッケージの開発中はソースコードの修正は頻繁に行うことになりますが、デフォルトのJuliaでは一度usingしたパッケージはその時点で確定してしまいます。ソースコードを変更後、再度usingしても反映されません(プリコンパイルが走らない)。毎回REPLやJupyterを再起動しないとソースコードの修正が反映されない・・となると辛すぎますよね。
Reviseパッケージを用いるとソースコードを変更後、再度のusingも不要で修正が反映されます!
パッケージモードで
(@v1.4) pkg> add Revise
して、~/.julia/config に下記二つのファイルを作成します。(Using Revise by default)
startup.jl
atreplinit() do repl
try
@eval using Revise
@async Revise.wait_steal_repl_backend()
catch e
@warn(e.msg)
end
end
startup_ijulia.jl
try
@eval using Revise
catch e
@warn(e.msg)
end
これでREPLやJupyterを立ち上げるとデフォルトでReviseが利く状態になります。
Reviseを用いない場合
Reviseを用いていない場合の挙動を見ていきます。先ほど作成した src/Example.jl を開いてみます。
module Example
greet() = print("Hello World!")
end # module
となっているかと思います。REPLやJupyterで
julia> using Example
julia> Example.greet()
Hello World!
となります。Example.jl を
module Example
greet() = print("Hello Julia!")
end # module
と変えてみます。再度REPLで実行しても
julia> Example.greet()
Hello World!
変わりません・・
Reviseを用いた場合
Reviseを用いた場合、二度目の実行は
julia> Example.greet()
Hello Julia!
となり、修正が反映されています!
開発パッケージへの依存パッケージの追加
ExampleパッケージにLinearAlgebraパッケージを追加する例です。 ] でパッケージモードに入り
(@v1.4) pkg> activate Example
Activating environment at `%JULIA_PKG_DEVDIR%\Example\Project.toml`
(Example) pkg> add LinearAlgebra
(Example) pkg> activate
Activating environment at `%USER_HOME%\.julia\environments\v1.5\Project.toml`
(@v1.4) pkg> up Example
で追加されます。他の開発パッケージへの依存を追加する場合は add ではなく dev を用います。
(Example) pkg> dev Example2
JuliaのIDE
VSCode
この記事を書いた当時はJuliaのIDEとしてAtom + Junoを紹介していたのですが、今は圧倒的にVSCodeをオススメします。
- REPLの動作がVSCodeの方が速い。ターミナルウィンドウはCtrl+Jで表示の切り替え。
- Julia FormatterのExtensionがある。コードが保存された状態でAlt+Shift+Fで適用。
- Git Graphが素晴らしい。
- LaTexの開発環境としてもVSCodeの方が快適。
Atom + Juno
AtomはGitHubが開発したオープンソースのテキストエディタです。様々なパッケージを追加して機能を拡張できます。話が逸れますがLaTeXやる人はtexliveとAtomと以下のパッケージを入れると環境が整うかと思います。実装したい数式をLaTeXで整理しておいてプレビューの数式を確認しながら実装する、実装しながら気付いたLaTeXの資料の誤りを修正する、というサイクルがやりやすいです。
-
メニューの日本語化
- japanese-menu
-
LaTeX用パッケージ
- latex
- language-latex
- latexer
- pdf-view
(texliveを入れるときはISOイメージから入れた方が良いですね。。ハマりました。)
AtomをJuliaのIDEに拡張するJunoの画面はこんな感じです。
レイアウトは自由ですが、この例では
- 左上にソースコード
- 左下にREPL
- 右上にWorkspaceとPlot Pane
- 右下にDebugger
を表示してみています。AtomにJunoを導入するには uber-juno パッケージをインストールします。
- ソースコードのあるコードにプロンプトがある状態で Shift+Enter でそのコードを実行
- 各変数が保持している値を確認できるWorkspace
- グラフを描画するPlot Pane
- ブレークポイントやステップ実行が可能なDebugger
- REPLを裏にもう一つ起動しておいてくれるので、REPLを閉じて(Stop Julia [Ctrl+J, Ctrl+K])新たに開くときに待ちが短い。
などJuliaの開発をサポートしてくれます。
Debuggerの使い方
Example.jl を次のように編集してみます。
module Example
function example(len, n)
xs = []
for i in 1:n
push!(xs, randn(len))
end
return xs
end
end # module
長さlenの正規乱数ベクトルをn本持つリストを返す、という関数です。この example() にブレークポイントを設定して、JunoのDebuggerを起動するには次のようにします。
(@v1.4) pkg> add Debugger # Debuggerをインストール。初回のみ。
julia> using Debugger
julia> using Example
julia> breakpoint(Example.example) #ブレークポイントの設定
julia> Juno.@run Example.example(5, 10) # Debuggerの起動
Debugger Paneで「Debug: Next Line (Shift+F10)」で一行ずつ実行しながら、Workspace Paneで各変数の値を確認することができます。先ほど載せたJunoの画面が、この例でDebuggerを実行しているときのものになります。
ブレークポイントは行番号の左側をクリックすることでも設定できます。デバッグの途中で、ブレークポイントを追加で設定/解除もできます。ブレークポイントが設定されると行番号の左側に赤ポチが現れます。
テスト
テストは test/runtests.jl に書きます。 Example/test/runtests.jl を次のように編集してみます。
using Example
using Test
@testset "Example.jl" begin
len = 5
n = 10
xs = Example.example(len, n)
@test length(xs) == n
for x in xs
@test length(x) == len
end
end
example関数が指定したn本のベクトルを返してくるか、各ベクトルの長さはlenになっているか、を確認しています。
テストはパッケージモードで test [パッケージ名] で実行できます。
(@v1.4) pkg> test Example
Testing Example
Status `C:\Users\(ユーザー名)\AppData\Local\Temp\jl_BpDq2B\Manifest.toml`
[341bb147] Example v0.1.0 [`%JULIA_PKG_DEVDIR%\Example`]
[2a0f44e3] Base64
[8ba89e20] Distributed
[b77e0a4c] InteractiveUtils
[56ddb016] Logging
[d6f4376e] Markdown
[9a3f8284] Random
[9e88b42a] Serialization
[6462fe0b] Sockets
[8dfed614] Test
Test Summary: | Pass Total
Example.jl | 11 11
Testing Example tests passed
以上です。