プログラミング言語Rustのご紹介

68dad178ea4fa6aa86862b3a66a15306?s=47 Yuki Toyoda
August 22, 2020
3.9k

 プログラミング言語Rustのご紹介

Zli x サイバーエージェント合同LT会にて発表した内容です。

68dad178ea4fa6aa86862b3a66a15306?s=128

Yuki Toyoda

August 22, 2020
Tweet

Transcript

  1. プログラミング⾔語 Rust のご紹介 次の 40 年のためのプログラミング⾔語 2020-08-22 Zli × サイバーエージェント

    合同LT
  2. ほんとうに Rust の話しかしません。⼈事ごめん。 2020-08-22 Zli × サイバーエージェント 合同LT

  3. ⽬次 ⾃⼰紹介 Rust とは? Rust の特徴的な機能 Rust の⽇本のコミュニティ活動 2020-08-22 Zli

    × サイバーエージェント 合同LT
  4. ⾃⼰紹介 yuki (Twitter: @helloyuki_ ) 社会⼈ 6 年⽬(まだ 20 代!)

    Rust.Tokyo & RustFest Global オーガナイザー 共著『実践 Rust プログラミング⼊⾨』 使える⾔語: Japanese, English (UK), French 2020-08-22 Zli × サイバーエージェント 合同LT
  5. ⾃⼰紹介 作っているもの TD4(4bit CPU)のエミュレータ https://github.com/yuk1ty/cpu-4bit-emulator RISC-V のエミュレータ(現在進⾏中) https://github.com/yuk1ty/risc-v-emu コントリビューション Servo:

    Firefox が開発する次世代ブラウジングエンジン 2020-08-22 Zli × サイバーエージェント 合同LT
  6. ⾃⼰紹介 事前アンケートでリクエストをいただいたので、答えます。 Rust を使いはじめたきっかけ JVM 系⾔語への不満 前職では、⾦融機関のリスク管理計算機を Java で作っていたが、並⾏並列処理由 来の不具合があまりにも多かった。ならびにメモリ制御(GC)への不満。

    Rust には前職で出会う。Java しか経験がなかったが、Rust のデザインが⾮常に合 理的に⾒えた。 2020-08-22 Zli × サイバーエージェント 合同LT
  7. ⾃⼰紹介 Rust を使いはじめたきっかけ 同時期に Go もはやりだしていた。 ⼀応先輩に勧められて両⽅触った。 Java の抽象化の機構がすごく好きだったので、Rust の抽象化の機構もしっくりき

    た。 私はものが動くよりもプログラムやアルゴリズムが美しいことの⽅が好きなん だと思う なので、それ以来 Rust を使⽤している。 2020-08-22 Zli × サイバーエージェント 合同LT
  8. Rust とは? 2020-08-22 Zli × サイバーエージェント 合同LT

  9. Rust とは? 2015 年にリリースされたシステムプログラミング⾔語。 A language empowering everyone to build

    reliable and efficient software (Rust Official) but especially folks who didn't think systems programming was for them (Ashley Williams) fn main() { let user_name = "Yuki"; println!("Hello, World!: {}", user_name); } 2020-08-22 Zli × サイバーエージェント 合同LT
  10. ⾔語としての特徴 とにかく速い。 平均して Go より速い。Java より速い。C/C++ 並の速度が出る。 速い上にゼロコスト抽象化によって、コードのきれいさを⼀切諦めずに実装でき る。 DX

    と速さがトレードオフにならない。 実⾏時に未定義動作(UB; Undefined Behaviour)が発⽣しない。 use-after-free を始めとするメモリ安全でない実装はコンパイル時に弾く。 強⼒な型システムによって、並⾏処理時に発⽣するデータ競合もコンパイル時に弾 く。 2020-08-22 Zli × サイバーエージェント 合同LT
  11. ⾔語としての特徴 Shared XOR Mutable 参照は共有できる。 参照はミュータブルにできる。 しかし、ミュータブルで共有可能な参照は作れない。 多くの事故を防ぐ。 ⼀貫性と直交性を重視したエルゴノミックな⾔語デザイン 体感、書いたとおりに動く。

    トリッキーな実装になりづらい設計がされている。 パターンマッチングなどの ML 系の⽂法の採り⼊れ。 2020-08-22 Zli × サイバーエージェント 合同LT
  12. 利⽤事例 国外: Google, Amazon, Facebook, Microsoft, etc 国内: FORCIA, CADDi,

    DeNA, LayerX, OPTiM, etc 海外では、 Go や Node.js でできた既存システムからの移⾏事例が多い。 国内では、移⾏事例より最初から Rust を⼊れてみた系が多い。 2020-08-22 Zli × サイバーエージェント 合同LT
  13. 将来性 Chromium の⼀部コンポーネントへの導⼊が検討されはじめている? Amazon や Microsoft はすでに公式に Rust を使⽤したプロダクトを作ったことを発表し ている。

    Linux への導⼊の噂。 Rust Foundation の設⽴を 2020 年中に⾏うことが発表された。 Rust は次の 40 年のための⾔語 Rust: A Language for the Next 40 Years - Carol Nichols https://www.youtube.com/watch?v=A3AdN7U24iU 2020-08-22 Zli × サイバーエージェント 合同LT
  14. ⾔語としての魅⼒ 下記は個⼈的な意⾒。 環境構築が頭おかしいくらい楽。 変な罠が少ない。型が強いので、コンパイルを通せば書いたとおりに動く。⾔語特有の 暗黙の了解みたいなものが少ない。 GC がないのでメモリ使⽤量の予測を⽴てやすい。 雑に書いてもまずまず⾼速だが、適切にチューニングすると極限まで⾼速化できる。 Rust をやると低レイヤーまで勉強できる。

    書いていて気持ちいい。← 重要 2020-08-22 Zli × サイバーエージェント 合同LT
  15. ⾔語としてもう少しがんばる必要があると思っているところ すべての⾔語は何かしらのトレードオフの上に成り⽴っているので、思うところを書く。 Bjarne Stroustrup ⽒の講演を 2 年前に東京⼤学で聞いたのだが、その際にこんな質問が あった。 質問者「Rust についてどう思っていますか?C++

    と似たことを実現しようとして いますが」 Bjarne さん「よく知らないんだけど、C++ には⻑い歴史によって積み重ねられたエ コシステムがある。それを揃えるのは⼤変だろうね」 同意⾒。 2020-08-22 Zli × サイバーエージェント 合同LT
  16. ⾔語としてもう少しがんばる必要があると思っているところ エコシステムの充実と成熟が急務であり、かつもっともユーザーに求められていること でもある。 とくに Web 系の⼈間からすると、Spring (Java)、Akka (Scala)、Rails (Ruby) クラ

    スの強⼒なフレームワークがないように思う。 actix-web が有⼒ではある。 ただでさえ学習コストが⾼い⾔語だが、まだまだチュートリアルが少ない。 中級者以上のチュートリアルの充実が急務。⼊⾨編はかなり多く存在するが、中級 者向け、上級者向けワークアラウンドとなるとまだまだない。 『Effective Rust』の執筆が待たれる。 ただ、これらはユーザーが増えていくと⾃然と解決するものなので、Rust のファンを作 るのが⼤事 2020-08-22 Zli × サイバーエージェント 合同LT
  17. Rust の特徴的な機能 2020-08-22 Zli × サイバーエージェント 合同LT

  18. Rust の特徴的な機能を⼀通り⾒る 時間の都合上すべては無理かもしれない。 安全性 参照 所有権 ライフタイム 関数型プログラミング由来 デフォルトがイミュータブル 代数的データ型とパターンマッチング

    その他 2020-08-22 Zli × サイバーエージェント 合同LT
  19. 参照 ダングリングポインタなどの危険な操作はコンパイルエラーになる。 fn definitly_one() -> &i32 { // この変数のスコープは関数末尾まで。 let

    i = 1; // ローカル変数の参照を返す = danglig pointer // これは後述のライフタイムと関連して、コンパイルエラーとして検出される。 &i } 2020-08-22 Zli × サイバーエージェント 合同LT
  20. 所有権 Rust では、値には 1 つの所有者がいる。所有権がなくなると値は破棄される。 値は借⽤という機能によって貸し借りできる。 fn main() { //

    メモリを確保する。 let text1 = String::from("text"); // text1 はこの時点で解放され、新たに text2 ⽤のメモリが確保される。 let text2 = text1; // 解放されている箇所にアクセスしているので、これはコンパイルエラーとして検出される。 println!("{}", text1); } 2020-08-22 Zli × サイバーエージェント 合同LT
  21. 所有権 コンパイルエラーは次のように出る。 error[E0382]: borrow of moved value: `text1` --> src/main.rs:4:20

    | 2 | let text1 = String::from("Hello, world"); | ----- move occurs because `text1` has type `std::string::String`, which does not implement the `Copy` trait 3 | let text2 = text1; | ----- value moved here 4 | println!("{}", text1); | ^^^^^ value borrowed here after move 2020-08-22 Zli × サイバーエージェント 合同LT
  22. 所有権 スコープを抜けても、所有権は移動する。 { // この時点で text は有効になる。 let text =

    "Hello"; } // スコープが終了し、text はもう有効ではなくなる。 2020-08-22 Zli × サイバーエージェント 合同LT
  23. 所有権 何が起きているのか 要するに、所有者を失った値はどんどん破棄されていく。 ムーブ呼ぶ。 ムーブされた値のあったメモリ領域は未定義状態になる。 そこを参照しようとしてもコンパイルエラーで弾く。 2020-08-22 Zli × サイバーエージェント

    合同LT
  24. 所有権 何が起きているのか 次のコードを… // S(1) を t に束縛する。 let t

    = S(1); // 想定では、t の値は a にムーブする。 let a = t; 2020-08-22 Zli × サイバーエージェント 合同LT
  25. 所有権 何が起きているのか かなり簡略化して図⽰すると次のようになる。 これがムーブ。 2020-08-22 Zli × サイバーエージェント 合同LT

  26. ライフタイム ダングリングポインタの回避のための仕組みで、参照のスコープを解析する。 ライフタイムのおかげでファイルディスクリプタなどの破棄も、任せておける。 { let r; { let x =

    5; // r は x への参照をもつが… r = &x; } // x はこのスコープを抜ける瞬間にムーブ。 // スコープ外の参照を使⽤しようとしている→ ライフタイム制約違反 println!("r: {}", r); } 2020-08-22 Zli × サイバーエージェント 合同LT
  27. Borrow Checker 所有権やライフタイムは、コンパイル時に違反が検出される。 AST → HIR → MIR → LLVM

    IR → Machine Code の順で Rust コンパイラはコンパイル していく。 MIR という中間⾔語でこのあたりの操作(Borrow Checker)が確認されている。 2020-08-22 Zli × サイバーエージェント 合同LT
  28. Borrow Checker 下記コードの MIR を読んでみる。 fn main() { let r;

    { let x = 11; r = x; } } 2020-08-22 Zli × サイバーエージェント 合同LT
  29. Borrow Checker 読みやすさのために出⼒内容を⼀部削除している。 fn main() -> () { let mut

    _0: (); // return place in scope 0 at src/main.rs:1:11: 1:11 let _1: i32; // in scope 0 at src/main.rs:2:9: 2:10 scope 1 { debug r => _1; // in scope 1 at src/main.rs:2:9: 2:10 let _2: i32; // in scope 1 at src/main.rs:4:13: 4:14 scope 2 { debug x => _2; // in scope 2 at src/main.rs:4:13: 4:14 } } bb0: { StorageLive(_1); // scope 0 at src/main.rs:2:9: 2:10 StorageLive(_2); // scope 1 at src/main.rs:4:13: 4:14 _2 = const 11i32; // scope 1 at src/main.rs:4:17: 4:19 _1 = const 11i32; // scope 2 at src/main.rs:5:9: 5:14 _0 = const (); // scope 1 at src/main.rs:3:5: 6:6 StorageDead(_2); // scope 1 at src/main.rs:6:5: 6:6 StorageDead(_1); // scope 0 at src/main.rs:7:1: 7:2 return; // scope 0 at src/main.rs:7:2: 7:2 } } 2020-08-22 Zli × サイバーエージェント 合同LT
  30. デフォルトが不変(イミュータブル) 何も指定せず変数を宣⾔(Rust では束縛という)すると不変になる。 可変にするには、明⽰的に書く必要がある。 不変な変数に可変な操作を⾏おうとすると、コンパイルエラーになる。 fn main() { // x

    は不変な変数として宣⾔される let x = 5; // the value is 5 println!("the value is {}", x); // 不変で束縛した変数に新しい値を代⼊しようとした。 // コンパイルエラーになる。 x = 6; println!("the updated value is {}", x); } 2020-08-22 Zli × サイバーエージェント 合同LT
  31. デフォルトが不変(イミュータブル) 先ほどのコードは、変数が可変な事を⽰す let mut と書くことによって動作させられ る。 fn main() { let

    mut x = 5; println!("the value is {}", x); x = 6; println!("the updated value is {}", x); } 2020-08-22 Zli × サイバーエージェント 合同LT
  32. 代数的データ型とパターンマッチング Rust ではいたるところに代数的データ型(ADT; Algebraic Data Types)が登場する。 代数的データ型を組み合わせながら実装を進めていく。 #[derive(Clone)] pub enum

    Token { Number(i32), BoolValue(bool), Var(String), Add(Box<Token>, Box<Token>), Multiply(Box<Token>, Box<Token>), LessThan(Box<Token>, Box<Token>), } 2020-08-22 Zli × サイバーエージェント 合同LT
  33. 代数的データ型とパターンマッチング パターンマッチングして、条件に応じた処理を書ける。 impl Token { pub fn is_reducible(&self) -> bool

    { use Token::*; match *self { Number(_) => false, BoolValue(_) => false, Var(_) => true, Add(_, _) => true, Multiply(_, _) => true, LessThan(_, _) => true, } } } 2020-08-22 Zli × サイバーエージェント 合同LT
  34. 代数的データ型とパターンマッチング null は Option という代数的データ型になっている。 // だいぶ省いて記載している enum Option<T> {

    Some(T), None, } 2020-08-22 Zli × サイバーエージェント 合同LT
  35. 代数的データ型とパターンマッチング エラーハンドリングは Result という代数的データ型を使⽤する。 正常系と異常系の処理を司っているという情報を明⽰的にコードに落とせる点で良いデ ザイン。 // だいぶ省いて記載している enum Result<T,

    E> { Ok(T), Err(E), } 2020-08-22 Zli × サイバーエージェント 合同LT
  36. 代数的データ型とパターンマッチング fn main() { let ans_result = less_than_hundred_add(1, 2); match

    ans_result { Ok(ans) => println!("{}", ans), Err(err) => eprintln!("{:?}", err), } } #[derive(Debug)] struct CalcErr; fn less_than_hundred_add(left: i32, right: i32) -> Result<i32, CalcErr> { if left > 100 || right > 100 { Err(CalcErr) } else { Ok(left + right) } } 2020-08-22 Zli × サイバーエージェント 合同LT
  37. その他 要するに型を⽤いた堅牢なデザインを可能にしている。 ⼀⽅で、強⼒な型推論のおかげで型を注釈する必要はほぼない。 トレイト(アドホック多相)やジェネリクス(パラメトリック多相)といった抽象化の 仕組みがあり、オーバーヘッドを気にせず使⽤できる(ゼロコスト抽象化)。 わかりやすいコンパイルエラーメッセージ。 神ビルドツール cargo 2020-08-22 Zli

    × サイバーエージェント 合同LT
  38. Rust の⽇本のコミュニティ活動 2020-08-22 Zli × サイバーエージェント 合同LT

  39. Rust の⽇本のコミュニティ活動 最初は会社で Rust を使うために登壇していた。 Rust コミュニティに集まる⼈が好きで、気づいたらいろいろ開いていた。 Rust はシステムプログラミング⾔語なので、Web 業界以外の⽅も多くいる。

    カンファレンスや勉強会(東京) Rust.Tokyo Rust LT Online rust-jp Slack 翻訳活動 2020-08-22 Zli × サイバーエージェント 合同LT
  40. Rust.Tokyo ⽇本初の Rust カンファレンスを 2019 年 10 ⽉ 26 ⽇に開催した。

    会場の都合で 200 名までの参加だ ったが、肌感ではそれ以上の⼈数 が集まりそうだった。 2020-08-22 Zli × サイバーエージェント 合同LT
  41. Rust LT Online これまで東京で開催していた Rust LT がオンラインになった。 第 1 回開催時には、全国から参加者が集まった。

    2020-08-22 Zli × サイバーエージェント 合同LT
  42. rust-jp Slack Slack グループが存在する。 https://rust-jp.herokuapp.com/ 2020-08-22 Zli × サイバーエージェント 合同LT

  43. 翻訳活動 数々のドキュメントが、有志によって翻訳されている。 下記サイトに⼀覧が記載されている。 Rust の⽇本語ドキュメント/Japanese Docs for Rust: https://doc.rust-jp.rs/ 2020-08-22

    Zli × サイバーエージェント 合同LT
  44. はじめよう $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

    $ cargo new hello_rust --bin $ cd hello_rust $ cargo run Hello, world! 2020-08-22 Zli × サイバーエージェント 合同LT
  45. お知らせ 2020-08-22 Zli × サイバーエージェント 合同LT

  46. RustFest Global やるよ 今年は Rust.Tokyo はコロナの影響で中⽌の判断をした。 RustFest と Rust.Tokyo が合流し、グローバルカンファレンスを開く。

    ⽇本語で話していただいて OK(事前録画が必要などの制約はあり)。 APAC 想定なので、中国(本⼟、台湾、⾹港)、韓国、マレーシア、オーストラリアな どからも期待。 RustFest goes Global: https://blog.rustfest.eu/rustfest-goes-global 2020-08-22 Zli × サイバーエージェント 合同LT
  47. 質問とか 2020-08-22 Zli × サイバーエージェント 合同LT

  48. 質問の受け付け このあと Twitter にスライドをシェアするので、そのツイートにコメントください。 懇親会には出られません。ごめんなさい。 なんでもいいです。 会社の話をまったくしなかったので、普段の仕事の話とか。 がんばって答えます。 Gotty NG

    が出ない限りは 2020-08-22 Zli × サイバーエージェント 合同LT