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

In Rust We Trust

In Rust We Trust

Brief overview of Rust presented at LambdaConf 2015.

Alex Burkhart

May 23, 2015
Tweet

More Decks by Alex Burkhart

Other Decks in Technology

Transcript

  1. "The goal is to design and implement a safe, concurrent,

    practical, static systems language." — Rust Project FAQ
  2. "Rust keeps the C abstract machine model but innovates on

    the language interface." — Raphael Poss, Rust for Functional Programmers
  3. Immutability by Default fn main() { let x = 0;

    x = 1; // => error: // re-assignment of immutable variable `x` let mut y = -10; y = 20; // => ok! }
  4. Type Inference fn double(n: u32) -> u32 { n *

    n } fn main() { let x = 500; let y = double(250); let z = x + y; }
  5. Enums enum Coffee { Hot(u8), // temp F Iced(bool), //

    still has ice Instant, } fn main() { let first_cup: Coffee = Coffee::Iced(true); let second_cup: Coffee = Coffee::Hot(212); println!("Drink {:?} then {:?}.", first_cup, second_cup); }
  6. Destructuring fn drinkable(cup: Coffee) -> bool { match cup {

    Coffee::Hot(120...150) => true, Coffee::Iced(x) => x, _ => false, } }
  7. Traits impl Eq for String { /* details omitted */

    } impl Hash for String { /* details omitted */ } impl<K, V> MyHashMap<K,V> where K: Eq + Hash { // details omitted } fn main() { let map: MyHashMap<String, u32> = MyHashMap::new(); // compiles! } // note: not quite the std lib implementations...
  8. Iterators & Closures fn main() { let squares = (0..10).map(|n|

    n * n); for i in squares { println!("{:?}", i); } }
  9. Hygenic Macros fn main() { let v1 = vec![1,2,3]; //

    vec![] expands into: let mut v2 = Vec::with_capacity(3); v2.push(1); v2.push(2); v2.push(3); }
  10. Testing /// double will do the obvious. ex: /// ```

    /// assert_eq!(double(2), 4); /// ``` fn double(n: u32) -> u32 { n * 2 } #[test] fn double_zero_is_zero() { assert_eq!(0, double(0)); }
  11. Module System // in project_a/src/traffic/color.rs mod traffic { pub enum

    Color { Red, Yellow, Green }; } // in project_b/src/main.rs extern crate project_a; use traffic::Color; fn main() { let stoplight = Color::Red; println!("Imported a {:?} stoplight!", stoplight); }
  12. Remarkable Error Messages fn main() { let coffee = Box::new(Coffee::Hot(85));

    let dupped = coffee.clone(); } :18:25: 18:32 error: type `Box<Coffee>` does not implement any method in scope named `clone` :18 let dupped = coffee.clone(); ^~~~~~~ :18:25: 18:32 help: methods from traits can only be called if the trait is implemented and in scope; the following trait defines a method `clone`, perhaps you need to implement it: :18:25: 18:32 help: candidate #1: `core::clone::Clone`
  13. Manual Memory Management • Pointer Arithmetic • Null Pointers •

    Double Frees • Never Frees • Dangling Pointers
  14. Unsafety = Memory Unsafety • Accessing Uninitialized Data • Writing

    Invalid Data • Breaking Aliasing Rules • Data Races • Calling Foreign Functions
  15. Single Responsible Owner fn main() { // allocate some memory

    let stoplight = Color::Red; // access value of stoplight println!("the value of stoplight: {:?}", stoplight); // owner `stoplight` falls out of scope // owner drops its property }
  16. Ownership is a Tree fn main() { let mut drink_caddie

    = Vec::new(); for _ in 0..4 { drink_caddie.push(Coffee::Hot(212)); } println!("all the coffee: {:?}", drink_caddie); // owner `coffee` falls out of scope // owner drops its property // drop the Vec --> drop each Coffee --> drop the u8 }
  17. Mutability fn main() { let mut coffee = Box::new(Coffee::Hot(85)); *coffee

    = Coffee::Hot(212); println!("the value of coffee: {:?}", coffee); }
  18. Ownership Transfer fn main() { let coffee_shop = Box::new(Coffee::Hot(85)); let

    customer = coffee_shop; println!("the value of customer: {:?}", customer); println!("the value of coffee_shop: {:?}", coffee_shop); // => error! use of moved value `coffee_shop`! }
  19. Borrowing fn main() { let showing = BluRay::Disc; let friend_a

    = &showing; let friend_b = &showing; println!("hooray! everyone can share! {:?}", showing); println!("hooray! everyone can share! {:?}", friend_a); println!("hooray! everyone can share! {:?}", friend_b); }
  20. Aliasing & Mutability: Pick One fn reheat(cup: &mut Coffee) {

    /* snip */ } fn main() { let mut coffee = Box::new(Coffee::Hot(85)); reheat(&mut coffee); println!("coffee temp: {:?}", coffee); // => coffee temp: Hot(180) }
  21. Data Race 1. 2+ threads accessing the same data 2.

    at least 1 is unsynchronized 3. at least 1 is writing
  22. Shared Nothing fn main() { let (tx, rx) = channel();

    for task_num in 0..8 { let tx = tx.clone(); Thread::spawn(move || { let msg = format!("Task {:?} done!", task_num); tx.send(msg).unwrap(); }).detach(); } for data in rx.iter() { println!("{:?}", data); } }
  23. Shared Immutable Memory fn main() { let (tx, rx) =

    channel(); let huge_struct = HugeStruct::new(); let arc = Arc::new(huge_struct); for task_num in 0..8 { let tx = tx.clone(); let arc = arc.clone(); Thread::spawn(move || { let msg = format!("Task {:?}: Accessed {:?}", task_num, arc.huge_name); tx.send(msg).unwrap(); }).detach(); } for data in rx.iter() { println!("{:?}", data); // 10x => Task N: Accessed I'M HUGE } }
  24. Mutation with Synchronization fn main() { let (tx, rx) =

    channel(); let huge_struct = HugeStruct::new(); let arc = Arc::new(Mutex::new(huge_struct)); for task_num in 0..8 { let tx = tx.clone(); let arc = arc.clone(); Thread::spawn(move || { let mut guard = arc.lock().unwrap(); guard.access_count += 1; let msg = format!("Task {:?}: Accessed Count {:?}", task_num, guard.access_count); tx.send(msg).unwrap(); // drop the arc -> drop the guard -> unlock the mutex }).detach(); } for data in rx.iter() { println!("{:?}", data); // 10x => Task N: Accessed Count: M } }
  25. Rust at LambdaConf An Introduction to Rust: Or, "Who Got

    Types in My Systems Programming!" Jared Roesch 11am-1pm Sunday