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

Rust: Systems Programming for All!

Rust: Systems Programming for All!

A talk given at General Assembly on 2017-06-06. Covers the value of Rust, with a focus on ownership and borrowing.

8f9e4181f2951ca8f21ed5c541686367?s=128

nikomatsakis

June 06, 2017
Tweet

Transcript

  1. 1 Systems Programming for All! Systems Programming for All!

  2. 2 What is Rust all about? Elegant code that runs

    fast. Code that does the right thing.
  3. 3 Two years old on May 15! •••

  4. 4

  5. 5 Photo credit: tao lin https://www.flickr.com/photos/taolin/8639700222/

  6. JavaScript / Ruby / Python / Java / C# /

    … 6 Virtual Machine or Runtime Native library C / C++
  7. 7 Images used without permission.

  8. 8 Algorithm “Learn All The Things”: Find shelf S with

    computer books. Let N = 1. While less than N books on shelf S { Borrow the Nth book from shelf S. Read it and return it. N = N + 1. }
  9. 9 Images used without permission.

  10. 10 Images used without permission.

  11. 11 C / C++

  12. [0] 12 void example() { vector<string> shelf; shelf.push_back(…); for (auto&

    book : shelf) { read(book); shelf.push_back(…); } } capacity length data [1] [2] [3] book shelf
  13. 13 Crash, read random data, wev C/C++ Java Throw exception

    JavaScript Do… something Python Something… slightly different Rust? Detect problem when compiling Iterator invalidation: modify while iterating ==> Runtime Error
  14. 14 foo.rs <machine code> <input> <output> “compilation” “execution” Rust: check

    ownership + borrowing Others: something goes wrong here
  15. “not mutable” owns [0] 15 capacity length data [1] [2]

    1. Every value is owned by a single variable. owns moved ~~~~~~~~~~~~~~~~ (a) Owner gets to decide whether it is mutable. ✅ ❌ ❌ “moved” ~~~~~~~~~~~~~~~~ fn example() { let mut shelf = Vec::new(); shelf.push(…); let shelf2 = shelf; shelf.push(…); print(shelf2.len()); shelf2.push(…); }
  16. borrows owns [0] 16 capacity length data [1] [2] `shelf`

    borrowed here book ~~~~~~~~~~~~~~~~ 2. Shared borrows make the value temporarily immutable. fn example() { let mut shelf = Vec::new(); shelf.push(…); for book in &shelf { read(book); shelf.push(…); } shelf.push(…); } ❌ “immutable while borrowed” ✅
  17. “mutably borrowed” owns [0] 17 capacity length data [1] [2]

    `shelf` mutably borrowed here book ~~~~~~~~~~~~~~~~~~~~~ 3. Mutable borrows have unique access to the value. borrows mutably ❌ ✅ ✅ make changes fn example() { let mut shelf = Vec::new(); shelf.push(…); for book in &mut shelf { edit(book); print(shelf.len()); } shelf.push(…); }
  18. 18 1. Every value is owned by a single variable.

    2. Shared borrows make the value temporarily immutable. 3. Mutable borrows have unique access to the value. shelf shelf book shelf book
  19. 19 Recap: Mutation while iterating C/C++ Maximally efficient Maximally dangerous

    Others Less efficient Risky ⛈⛈ Rust Maximally efficient Perfectly safe
  20. 20 “Must be this tall to write multi-threaded code” Idea

    credit: David Baron Mozilla Engineer Extraordinaire and All-Around Great Guy
  21. 21 Shared state and threads Message-passing Data parallelism C and

    C++, Java, C#, … C and C++, Java, C#, … Erlang, Go, JavaScript, … Rust Rust Rust Futures and Async I/O JavaScript, C#, … Rust
  22. 22 Message-passing

  23. 23 let book = channel.receive(); read(book); 1. Every value is

    owned by a single variable. ❌ “moved” moved let book = …; channel.send(book); ~~~~~~~~~~~~
  24. 24 Data parallelism

  25. 25 fn load_images(paths: &[PathBuf]) -> Vec<Image> { paths.iter() .map(|path| {

    Image::load(path) }) .collect() } For each path… …load an image… …create and return a vector. paths = [ “a.jpg”, “b.png”, …, “c.jpg” ] borrowed from caller
  26. 26 fn load_images(paths: &[PathBuf]) -> Vec<Image> { paths.par_iter() .map(|path| {

    Image::load(path) }) .collect() } Make it parallel paths = [ “a.jpg”, “b.png”, …, “c.jpg” ] extern crate rayon; Third-party library
  27. 27 fn load_images(paths: &[PathBuf]) -> Vec<Image> { let mut jpgs

    = 0; paths.par_iter() .map(|path| { if path.ends_with(“.jpg”) { jpgs += 1; } Image::load(path) }) .collect() } How many jpgs seen so far? …add 1 to the counter. If current file name ends in “jpg”… 0 0 + 1 0 + 1 1 1 1
  28. 28 borrows mutably 1. Every value is owned by a

    single variable. 3. Mutable borrows have unique access to the value. fn load_images(paths: &[PathBuf]) -> Vec<Image> { let mut jpgs = 0; paths.par_iter() .map(|path| { if path.ends_with(“.jpg”) { jpgs += 1; } Image::load(path) }) .collect() }
  29. fn load_images(paths: &[PathBuf]) -> Vec<Image> { let mut jpgs =

    0; paths.par_iter() .map( ) .collect() } 29 borrows mutably borrows mutably |path| { if path.ends_with(“.jpg”) { jpgs += 1; } Image::load(path) } |path| { if path.ends_with(“.jpg”) { jpgs += 1; } Image::load(path) } 3. Mutable borrows have unique access to the value. ~~~~~~~~~ ❌ ~~~~~~~~~ ❌
  30. 30 Recap: Parallel execution Others Flexible ✅✅✅ Maximally dangerous Restrictive

    Perfectly safe Rust Flexible ✅✅✅ Perfectly safe
  31. 31 More examples… ( Foo vs Option<Foo> ) No null

    pointers Robust error handling Generic programming …
  32. 32 Unsafe

  33. Rust 33 Ownership and Borrowing Unsafe Code Raw Computer

  34. fn pass_safely(…) { if !car_coming() { } } Safe abstractions

    unsafe { drive_in_left_lane(); } Trust me. Validates input, etc. 34
  35. 35 Community Photo credit: David McSpadden https://www.flickr.com/photos/familyclan/15535822737/

  36. 36

  37. 37 From http://jvns.ca/blog/2016/09/11/rustconf-keynote/ Open and welcoming

  38. 38 https://www.meetup.com/BostonRust/
 Next meetup: June 28 in Cambridge http://boston-rust.herokuapp.com/ Boston

    area Worldwide rust-lang.org
 irc.mozilla.org, #rust, #rust-beginners doc.rust-lang.org/nightly/book/second-edition/ intorust.com ❤ A lso, stickers!