本記事は『詳解Rustプログラミング』の「第1章 Rustとは」から一部を抜粋したものです。掲載にあたって編集しています。
Rustとは
Rustの世界に、ようこそ。Rustは「力を得られる」(empowering)プログラミング言語だ。表面を撫でただけでも、このプログラミング言語が、速度と安全性で卓越しているだけでなく、毎日でも楽しく使える言語だということが、わかるはずだ。
Rustでプログラミングを始めたら、たぶんやめられなくなるだろう。そして、本書を読めば、Rustプログラマとしての自信を得られるだろう。ただし、本書はプログラミングを最初から教えるわけではない。本書はRustを、次に使う言語として考えている人、実践的で使えるサンプルの実装法を学習するために書かれている。本書のサンプルのうち、比較的大きなものを、次に示す。
- マンデルブロート集合のレンダラ
- grep風な検索や、16進ダンプのユーティリティ
- CPUエミュレータ
- ジェネレーティブアート
- データベース
- HTTPやNTPのクライアント
- LOGO言語のインタープリター
- OSカーネル
この一覧を見ればわかるように、本書で学べるのはRustだけではない。システムプログラミングと低レベルプログラミングも紹介する。本書を読み進めるうちに、オペレーティングシステム(OS)の役割や、CPUの仕組み、コンピュータの時計を正しく合わせる機構、そしてポインタとは何か、データ型とは何かも学習できる。コンピュータ内部のシステムが、どのように共同作業をしているのかも理解できるようになる。構文だけでなく、それ以上の事項を学ぶことで、Rustが作られた理由や、その使命も、わかってくるだろう。
Rustは、どこで使われているのか
2016年から2020年にかけてStack Overflowが行った年次調査で、Rustは「開発者がもっとも愛するプログラミング言語」の栄誉を勝ち取った。たぶん、だからこそ、以下に示す大規模テクノロジーリーダー各社が、Rustを採用してきたのだろう。
- AWS(Amazon Web Services)は2017年から、同社のAWS LamdaとAWS Fargateによるサーバーレスコンピューティングを提供するのにRustを使っている。このことがRustの、さらなる進出に一役買った。同社は、EC2(Elastic Compute Cloud)を提供するため、Bottlerocket OS とAWS Nitro Systemも書いている。
- Cloudflareは、パブリックDNS、サーバーレスコンピューティング、パケットインスペクションを含む同社の多くのサービスをRustで開発している。
- Dropboxは、エクサバイト単位のストレージを管理する同社のバックエンドウェアハウスを、Rustによって再構築した。
- Googleが開発するAndroidのうち、たとえばBluetoothモジュールなどに、Rustが使われている。Chrome OSのcrosvmコンポーネントにもRustが使われ、同社の新しいOSであるFuchsiaでもRustが重要な役割を演じている。
- Facebookは、Web、モバイル、APIのサービスを駆動するのにRustを使っているほか、Hackプログラミング言語用のHipHop Virtual Machine(HHVM)の一部にもRustを使っている。
- MicrosoftのAzureプラットフォームでは、IoTサービス用のセキュリティデーモンを含むコンポーネントが、Rustで書かれている。
- Mozillaは、1500万行のコードを含むFirefox Webブラウザを増強するのにRustを使っている。同社によるRust-in-Firefoxプロジェクトのうち、最初の2つ(MP4メタデータパーサとテキストエンコーダ/デコーダ)で、全体的な性能と安定性が改善された。
- GitHubとMicrosoftがサポートするnpm社は、Rustを使って「毎日130億回以上のパッケージダウンロード」を届けている。
- Oracleは、Goのリファレンス実装における問題点を克服するため、Rustでコンテナランタイムを開発した。
- SamsungのIoTサービス用ファームウェアバックエンドであるHubには、同社がサポートするSmartThingsを介して、Rustが使われている。
Rustには十分に高い生産性があるので、急速に展開中の新企業にも採用されている。その例を次に示す。
- Sourcegraphの、構文を強調する処理では、どの言語にもRustが使われている。
- Figmaは、マルチプレイヤーサーバーの性能を左右するコンポーネントにRustを採用した。
- Parityは、EthereumブロックチェーンのクライアントをRustで開発している。
Rustとは何か?
プログラミング言語としてのRustの特徴は、不正なデータアクセスをコンパイル時に防止できるという点だ。Microsoftのセキュリティレスポンスセンター(MSRC)によるリサーチプロジェクトも、そしてChromiumブラウザのプロジェクトも、不正なデータアクセスに関する問題が、深刻なセキュリティバグの7割程度を占めていることを示している。Rustは、その種のバグを排除するので、プログラムは実行時のコストを増やすことなくメモリ安全になるという保証が得られる。
他の言語でも同レベルの安全性を提供することは可能だが、それにはプログラムの実行時に行うチェックを加える必要があるので、遅くなってしまう。Rustは、図1-1に示す独自の空間をニッチとして、それらの領域から脱している。
プロフェッショナルコミュニティとしてのRustの特徴は、意志決定のプロセスで明示的に複数の価値(values)が重視されることだ。このポリシーは広く行き渡っている。Rustコミュニティでは広報が歓迎され、各自の相互作用は、行動規範によって管理される。Rustコンパイラのエラーメッセージさえ、驚くほど役立つものになっている。
2018年の終わり頃まで、Rustホームページを訪れたビジターは、次のような(技術的な重みのある)メッセージで迎えられた。
Rustは実行が猛烈に高速でセグメンテーションフォールトを防止しスレッド安全性を保証するシステムプログラミング言語です。
それからRustコミュニティはメッセージの言いまわしを変えて、ユーザー(および将来そうなる可能性のある人たち)を中心に据えることになった(表1-1)。
Rustはシステムプログラミング言語に分類されるが、それでは、なんだか専門的な、ほとんど「選ばれた少数のためのプログラミング」と思われるかもしれない。けれども多くのRustプログラマが、この言語を他の多数の領域に応用できることを発見してきた。安全性と生産性と細やかな制御は、すべてのソフトウェア技術プロジェクトに有益だ。そればかりかRustは、そのコミュニティの包括的な姿勢によって、「多様な関心を表明する新しい声の絶え間ない流れ」から恩恵を受けているのだ。
Rustの3つの特色
何かを作れると確信できるかどうかは、使うツールに左右される。Rustなら「作りたくても怖くて手を出せなかったソフトウェア」を構築できる。Rustとは、どんなツールなのだろうか。前節で論じた3つの原則から、この言語の中心となる3つの特色が導かれる。
- 性能
- 並行性
- メモリ効率
性能(パフォーマンス)
Rustは、コンピュータで利用できるパフォーマンスを、すべて提供する。よく知られているように、Rustはガベージコレクションに頼ることなくメモリ安全性を達成している。
とはいえ「より高速なプログラム」という約束には問題があって、CPUの速度は有限である。だからソフトウェアを、より速く走らせるためには、行う仕事を減らす必要がある。それなのに、この言語は大きい。この矛盾を解決するために、Rustではコンパイラに重荷がかかる。
Rustコミュニティは、「コンパイラの仕事が少ないシンプルな言語」より、「コンパイラの仕事が多い比較的大きな言語」を好む。Rustコンパイラは、プログラムのサイズとスピードの両方を積極的に最適化する。また、Rustには次のように、それほど自明ではないトリックもある。
- キャッシュしやすいデータ構造がデフォルトで提供される。Rustのプログラムでは、データを格納するのに、(ポインタを使って深くネストされた木構造ではなく)配列を使うのが普通だ。こういうのはデータ指向プログラミングと呼ばれている。
- モダンなパッケージマネージャー(cargo)を利用できるので、何万という数のオープンソースパッケージを簡単に利用できる。これと比べれば、CやC++における一貫性はずっと弱く、多数の依存関係を持つ大規模なプロジェクトの構築が困難になりやすい。
- メソッドは、いつも静的にディスパッチされる(ただし動的なディスパッチを明示的に要求することもできる)。これによってコンパイラは、ときには関数コールのコストを完全に取り除くところまで、積極的にコードを最適化できる。
並行性
ソフトウェアエンジニアが1台のコンピュータに「同時進行で複数の仕事をやらせる」のは、そもそも難しいことだと証明されている。OSに関する限り、2本の独立した実行スレッドは、互いを破壊することさえできる(プログラマが深刻なミスを犯したら)。けれどもRustでは怖くない並行性(fearless concurrency)という表現が生まれている。このフレーズは「独立したスレッドの境界を安全に越えられます」という意味なのだ。スレッドの速度を制限する「グローバルなインタープリターロック」(GIL)は存在しない。これについては第2部で、その一部を探究する。
メモリ効率
Rustなら、メモリ要求を最小限に抑えたプログラムを作ることができる。必要なときは固定長の構造を使えるし、個々のバイトがどのように管理されるかもわかる。イテレーション(反復処理)やジェネリック型のような高いレベルの構造も、実行時のオーバーヘッドは最小限である。
Rustの隠し技はコミュニティ
プログラミング言語を育てるのに、ソフトウェアだけでは足りない。Rustチームは、参入者を歓迎するポジティブなコミュニティの育成でも、並外れた成果を収めた。Rustの世界では、どこに行っても礼儀正しく敬意のある待遇を得られるだろう。
Rustの決まり文句
Rustコミュニティのメンバーと会話をすると、すぐに特別な意味を持つ用語に遭遇するだろう。次にあげる用語を理解すれば、Rustがこのように進化した理由も、これから解決しようとしている問題も、理解しやすくなるだろう。
- Empowering everyone(誰にでも力を与える)―――能力や背景を問わず、すべてのプログラマの参入を歓迎する。プログラミング(とりわけ、システムプログラミング)は、恵まれた少数の人々のためにあるのではない。
- Blazingly fast(猛烈に速い)―――Rustは高速なプログラミング言語だ。ライバル言語の性能に匹敵する、あるいはそれを上回るプログラムを書くことができ、しかもよりたしかな安全性が保証される。
- Fearless concurrency(怖くない並行処理)―――同時的、並列的なプログラミングは、常に難しいと考えられてきた。Rust なら、ライバル言語に蔓延する一群のエラーから解放される。
- No Rust 2.0(Rust 2.0は来ない)―――いま書いたRustのコードは、将来のRustコンパイラでも必ずコンパイルできる。Rustは、今後何十年も依存できる信頼性の高いプログラミング言語を意図している。バージョンアップで後方互換性を失うことは決してない。だから斬新なメジャーバージョンのリリースは決して到来しないだろう。
- Zero-cost abstractions(ゼロコストの抽象)―――Rustから得られる機能には、ランタイムコストがかからない。Rustでプログラミングするとき、速度は安全性の犠牲にはならない。