Juliaの生きる道 (生成AI時代の開発体験)

Hiroshi Shinaoka & Satoshi Terasaki

私たちは, JuliaとRustという性質の異なる言語を科学技術計算に積極的に利用している. このような珍しい立ち位置にいるからこそ, 感じたことを記事にしてみた.

前提

Juliaを含め, Pythonなどの動的型付け言語は, 対話環境 (REPLやJupyter Notebook)での利用が気軽にできるのが良い. 実行結果をメモリに保持しつつ, 結果に応じて解析を加えたり, 結果を可視化したりすることが容易である. その中でもJuliaの際立つ特徴は, 静的型付け言語の性質も併せ持ち, 型安全なコードを書きやすく, 高速な実行速度を実現していることである. まとめると, Juliaの長所は,

  • 対話環境での使いやすさ
  • 静的型付け言語の性質も併せ持つ型安全性
  • 高速な実行速度により, 低層から高層までpure Juliaで記述可能 (→2言語問題の解消)
  • 優秀なパッケージシステムによる依存性解決

というところである.

一方, Rustは, メモリ安全性を重視し, 所有権システムを導入している. 所有権システムは, ガーベッジコレクションによるメモリ管理を行うJuliaやPythonとは対極的なアプローチである. JuliaやPythonでは, うっかり同じオブジェクトの可変参照を複数箇所で保持してしまい, 知らないうちにメモリの中身が変わっているというバグが発生しやすい.

一方, Rustの所有権システムは, コンパイル時にメモリ安全性を保証できる. 優秀なパッケージシステムがあることは, RustとJuliaの両方に共通しており, エコシステムを協力して育てやすい (どちらが優秀かという危険な話題には触れない). その代償として, コードの記述の複雑性は高く, 人間にとっての学習曲線は急峻である.

JuliaとRustの使い分け

以前の記事でも書いたが, これらの組み合わせは, 開発体験も良く, エコシステムも協力して育てやすい. 両方とも優秀なパッケージシステムがあるからこそ, RustをバックエンドとしたJuliaライブラリを作成しやすい.

Juliaは低レベルから高レベルまですべてのスタックを単一言語で原理的に書くことはできるが, 巨大なコードベースを最適化するコストは小さくない. JET.jlなどの静的解析ツールがあるといえ, 動的な書き方ができてしまう以上, 静的に保証できる範囲には限界がある. さらに, 高性能な並列実行ではスレッド起動コストやガーベッジコレクションのオーバーヘッドも無視できない. 最適化された巨大なコードを慎重に書くコストを払うべきかは, コードベースのサイズによる.

巨大なコードベースを複数のコンポーネントに分割し, 独立したJuliaパッケージとして公開できるのはJuliaの強みである. しかし, Juliaのパッケージ登録システムはGitHubのissueベースであり, 新しいパッケージや新しいバージョンが即時に公開されるわけではない. 相互に依存した多数のライブラリのバージョンを管理するのはとてもつらい.

個人的な体験では, 大規模なバックエンドコードを書くときは, AIエージェントの支援がある限り, Rustで書くのが心地よい. Rustコードは所有権関係の記述のため, 一見非常に複雑で, AIエージェントで生成したコードを人間がレビューしづらいと思うかもしれない. しかし, 実際には, 所有権関係はコンパイラが検証してくれるので, 人間はもっと高次の動作のチェック (アルゴリズムやデータ構造の正当性)に集中できる. また, 複数のパッケージ (crate)を単一のレポジトリにまとめて, 共通したバージョンを付与して管理することができる (workspace機能). crateの公開も, cargo publish を使えばターミナル上で即時にできるため, 複数のcrateを実質まとめて公開することができる.

このように言語を組み合わせると, しばしば「2言語問題」が発生することが歴史的に知られている. 例えば, C++とPythonの組み合わせは, もう2度と自分ではやりたくないぐらい, ライブラリの配布が難しいとか, 依存関係の管理が難しいとか, バージョンの管理が難しいとか, 数え切れない問題が発生する (お疲れ libsparseir, こんにちは sparse-ir-rs). RustとJuliaはC-FFIを通して簡単に連携し, 互いが優秀なパッケージシステムを利用できるので, このような問題は以前ほど深刻ではない.

このようなJuliaとRustを組み合わせたライブラリの配布には, まだ専門的知識が必要である. 上述したRustToolChain.jlは, このような問題を解決するためのツールである.この辺りは, 生成AIの力を借りれば, 今後さらに改善されていく.

JuliaとRustの境界は, 生成AIが発達すればするほど, Rustが有利な領域がひろがっていく. 自然言語で, データ解析から可視化まで一貫してできてしまう時代になったら (近いはず), 裏でAIがどんなツールを使うかは, 人間には関係ない. その時点で, 人間と機械をつなぐという動的プログラミング言語の役割を, 自然言語が置き換えることになる.

Updated: