Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Yuki Toyoda
August 22, 2020
6.6k

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

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

Yuki Toyoda

August 22, 2020
Tweet

Transcript

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

    View Slide

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

    View Slide

  3. ⽬次
    ⾃⼰紹介
    Rust とは?
    Rust の特徴的な機能
    Rust の⽇本のコミュニティ活動
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  4. ⾃⼰紹介
    yuki (Twitter: @helloyuki_
    )
    社会⼈ 6 年⽬(まだ 20 代!)
    Rust.Tokyo & RustFest Global オーガナイザー
    共著『実践 Rust プログラミング⼊⾨』
    使える⾔語: Japanese, English (UK), French
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

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

    View Slide

  7. ⾃⼰紹介
    Rust を使いはじめたきっかけ
    同時期に Go もはやりだしていた。
    ⼀応先輩に勧められて両⽅触った。
    Java の抽象化の機構がすごく好きだったので、Rust の抽象化の機構もしっくりき
    た。
    私はものが動くよりもプログラムやアルゴリズムが美しいことの⽅が好きなん
    だと思う
    なので、それ以来 Rust を使⽤している。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  8. Rust とは?
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  10. ⾔語としての特徴
    とにかく速い。
    平均して Go より速い。Java より速い。C/C++ 並の速度が出る。
    速い上にゼロコスト抽象化によって、コードのきれいさを⼀切諦めずに実装でき
    る。
    DX と速さがトレードオフにならない。
    実⾏時に未定義動作(UB; Undefined Behaviour)が発⽣しない。
    use-after-free を始めとするメモリ安全でない実装はコンパイル時に弾く。
    強⼒な型システムによって、並⾏処理時に発⽣するデータ競合もコンパイル時に弾
    く。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  11. ⾔語としての特徴
    Shared XOR Mutable
    参照は共有できる。
    参照はミュータブルにできる。
    しかし、ミュータブルで共有可能な参照は作れない。
    多くの事故を防ぐ。
    ⼀貫性と直交性を重視したエルゴノミックな⾔語デザイン
    体感、書いたとおりに動く。
    トリッキーな実装になりづらい設計がされている。
    パターンマッチングなどの ML 系の⽂法の採り⼊れ。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  12. 利⽤事例
    国外: Google, Amazon, Facebook, Microsoft, etc
    国内: FORCIA, CADDi, DeNA, LayerX, OPTiM, etc
    海外では、 Go や Node.js でできた既存システムからの移⾏事例が多い。
    国内では、移⾏事例より最初から Rust を⼊れてみた系が多い。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  14. ⾔語としての魅⼒
    下記は個⼈的な意⾒。
    環境構築が頭おかしいくらい楽。
    変な罠が少ない。型が強いので、コンパイルを通せば書いたとおりに動く。⾔語特有の
    暗黙の了解みたいなものが少ない。
    GC がないのでメモリ使⽤量の予測を⽴てやすい。
    雑に書いてもまずまず⾼速だが、適切にチューニングすると極限まで⾼速化できる。
    Rust をやると低レイヤーまで勉強できる。
    書いていて気持ちいい。← 重要
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  15. ⾔語としてもう少しがんばる必要があると思っているところ
    すべての⾔語は何かしらのトレードオフの上に成り⽴っているので、思うところを書く。
    Bjarne Stroustrup ⽒の講演を 2 年前に東京⼤学で聞いたのだが、その際にこんな質問が
    あった。
    質問者「Rust についてどう思っていますか?C++ と似たことを実現しようとして
    いますが」
    Bjarne さん「よく知らないんだけど、C++ には⻑い歴史によって積み重ねられたエ
    コシステムがある。それを揃えるのは⼤変だろうね」
    同意⾒。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  16. ⾔語としてもう少しがんばる必要があると思っているところ
    エコシステムの充実と成熟が急務であり、かつもっともユーザーに求められていること
    でもある。
    とくに Web 系の⼈間からすると、Spring (Java)、Akka (Scala)、Rails (Ruby) クラ
    スの強⼒なフレームワークがないように思う。
    actix-web が有⼒ではある。
    ただでさえ学習コストが⾼い⾔語だが、まだまだチュートリアルが少ない。
    中級者以上のチュートリアルの充実が急務。⼊⾨編はかなり多く存在するが、中級
    者向け、上級者向けワークアラウンドとなるとまだまだない。
    『Effective Rust』の執筆が待たれる。
    ただ、これらはユーザーが増えていくと⾃然と解決するものなので、Rust のファンを作
    るのが⼤事
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  17. Rust の特徴的な機能
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide

  19. 参照
    ダングリングポインタなどの危険な操作はコンパイルエラーになる。
    fn definitly_one() -> &i32 {
    //
    この変数のスコープは関数末尾まで。
    let i = 1;
    //
    ローカル変数の参照を返す = danglig pointer
    //
    これは後述のライフタイムと関連して、コンパイルエラーとして検出される。
    &i
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  20. 所有権
    Rust では、値には 1 つの所有者がいる。所有権がなくなると値は破棄される。
    値は借⽤という機能によって貸し借りできる。
    fn main() {
    //
    メモリを確保する。
    let text1 = String::from("text");
    // text1
    はこの時点で解放され、新たに text2
    ⽤のメモリが確保される。
    let text2 = text1;
    //
    解放されている箇所にアクセスしているので、これはコンパイルエラーとして検出される。
    println!("{}", text1);
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  22. 所有権
    スコープを抜けても、所有権は移動する。
    {
    //
    この時点で text
    は有効になる。
    let text = "Hello";
    } //
    スコープが終了し、text
    はもう有効ではなくなる。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide

  24. 所有権
    何が起きているのか
    次のコードを…
    // S(1)
    を t
    に束縛する。
    let t = S(1);
    //
    想定では、t
    の値は a
    にムーブする。
    let a = t;
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  25. 所有権
    何が起きているのか
    かなり簡略化して図⽰すると次のようになる。
    これがムーブ。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  26. ライフタイム
    ダングリングポインタの回避のための仕組みで、参照のスコープを解析する。
    ライフタイムのおかげでファイルディスクリプタなどの破棄も、任せておける。
    {
    let r;
    {
    let x = 5;
    // r
    は x
    への参照をもつが…
    r = &x;
    } // x
    はこのスコープを抜ける瞬間にムーブ。
    //
    スコープ外の参照を使⽤しようとしている→
    ライフタイム制約違反
    println!("r: {}", r);
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  27. Borrow Checker
    所有権やライフタイムは、コンパイル時に違反が検出される。
    AST → HIR → MIR → LLVM IR → Machine Code の順で Rust コンパイラはコンパイル
    していく。
    MIR という中間⾔語でこのあたりの操作(Borrow Checker)が確認されている。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  28. Borrow Checker
    下記コードの MIR を読んでみる。
    fn main() {
    let r;
    {
    let x = 11;
    r = x;
    }
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  32. 代数的データ型とパターンマッチング
    Rust ではいたるところに代数的データ型(ADT; Algebraic Data Types)が登場する。
    代数的データ型を組み合わせながら実装を進めていく。
    #[derive(Clone)]
    pub enum Token {
    Number(i32),
    BoolValue(bool),
    Var(String),
    Add(Box, Box),
    Multiply(Box, Box),
    LessThan(Box, Box),
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  34. 代数的データ型とパターンマッチング
    null は Option という代数的データ型になっている。
    //
    だいぶ省いて記載している
    enum Option {
    Some(T),
    None,
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide

  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 {
    if left > 100 || right > 100 {
    Err(CalcErr)
    } else {
    Ok(left + right)
    }
    }
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  37. その他
    要するに型を⽤いた堅牢なデザインを可能にしている。
    ⼀⽅で、強⼒な型推論のおかげで型を注釈する必要はほぼない。
    トレイト(アドホック多相)やジェネリクス(パラメトリック多相)といった抽象化の
    仕組みがあり、オーバーヘッドを気にせず使⽤できる(ゼロコスト抽象化)。
    わかりやすいコンパイルエラーメッセージ。
    神ビルドツール cargo
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide

  39. Rust の⽇本のコミュニティ活動
    最初は会社で Rust を使うために登壇していた。
    Rust コミュニティに集まる⼈が好きで、気づいたらいろいろ開いていた。
    Rust はシステムプログラミング⾔語なので、Web 業界以外の⽅も多くいる。
    カンファレンスや勉強会(東京)
    Rust.Tokyo
    Rust LT Online
    rust-jp Slack
    翻訳活動
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  40. Rust.Tokyo
    ⽇本初の Rust カンファレンスを
    2019 年 10 ⽉ 26 ⽇に開催した。
    会場の都合で 200 名までの参加だ
    ったが、肌感ではそれ以上の⼈数
    が集まりそうだった。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  41. Rust LT Online
    これまで東京で開催していた Rust LT がオンラインになった。
    第 1 回開催時には、全国から参加者が集まった。
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  45. お知らせ
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

  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

    View Slide

  47. 質問とか
    2020-08-22 Zli × サイバーエージェント 合同LT

    View Slide

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

    View Slide