The Rust

Programming Language

Safe - Concurrent - Fast

By - Davis Silverman

fn main() {
    println!("Hello, World!");
}

Who am I?

  • Some PL geek 
  • Video game developer hobbyist

What Is Rust?

  • Modern Idioms, the best of all worlds
    • Immutable by default
    • No null pointers
    • Zero Cost Abstractions
  • Strong ownership model
    • move semantics -- think affine types
    • pass by value (which includes references)
  • Memory safe without garbage collection
    • Library provided smart pointers
  • Hygienic Macros
    • Type-safe meta-programming

An Introduction

  • No implicit casting
  • Readable and precise grammar
  • Powerful pattern matching
fn fizzbuzz(num: uint) -> String {
    match (num % 3, num % 5) {
        (0, 0) => "FizzBuzz".to_string(),
        (0, _) => "Fizz".to_string(),
        (_, 0) => "Buzz".to_string(),
        (_, _) => num.to_string()
    }
}

fn main() -> () {
    for num in range(0u, 101) {
        println!("{}", fizzbuzz(num));
    }
} 

Whoa Whoa Whoa.

2 STRING TYPES?!?!?!

  • &'str is a reference, no allocation
  • String is an owned object, allocated on the heap
  • Think StringBuilder

Nouns and Verbs

struct Dog {
    name: String,
    age: uint,
}
impl Dog {
    fn new(name: String, age: uint) -> Dog {
        Dog { name:name, age:age }
    }
    fn bark(&self) -> String {
        format!("I am dog {}. I am {}", self.name, self.age)
    }
}
fn main() -> () {
    let hunter_dawg: Dog = Dog::new("Hunter".to_string(), 5);
    println!("{}", hunter_dawg.bark())
}

Note: using `format!` could allocate more than you want, using `write!` with a MemWriter could save more memory :)

Algebraic Data Types

  • For Strongly Typed Data (HTTP Headers)
#[deriving(Show)]
enum List<T> {
    Cons(T, Box<List<T>>),
    Nil,
}

fn main() {
    let list: List<i32> = Cons(1i32, box Cons(2, box Cons(3, box Nil)));
    println!("{}", list);
}

Ownership

  • Moves
  • References
  • Aliasing
/// This function takes ownership of the variable
fn move_and_destroy<T: std::fmt::Show>(c: T) {
    // Have to return it to be claimed again.
    println!("destroying a variable that contains {}" , c);
    // `c` will be destroyed in this scope, and the memory will be freed
}

///this function prints the value of d
fn borrow_variable<T: std::fmt::Show>(d: &T) {
    // Do not have to return the variable to let the caller reclaim it
    println!("variable, {} is borrowed!" , d);
}

///this function alters f
fn borrow_mut_variable(f: &mut f64) { 
    *f = 42.0; 
}

Named lifetimes

  • Intentionally explicit
  • To codify how long a reference is valid
  • Simpler than you think
#[deriving(Show, PartialEq)]
enum Token<'a> {
    Word(&'a str),
    Other(&'a str)
}

fn tokenize_string3<'a>(text: &'a str) -> Vec<Token<'a>> {
    let mut result = vec![];
    for cap in regex!(r"(\w+)|(\W+)").captures_iter(text) {
        let token =
            if cap.pos(1).is_some() {
                Word(cap.at(1))
            } else {
                Other(cap.at(2))
            };
        result.push(token);
    }
    result
}

http://www.randomhacks.net/2014/09/19/rust-lifetimes-reckless-cxx/

Zero Cost Abstractions

'Monomorphization'

fn print_area<T: HasArea>(shape: T) {
    println!("This shape has an area of {}", shape.area());
}

fn main() {
    let c = Circle { ... };

    let s = Square { ... };

    print_area(c);
    print_area(s);
}

Boxes

  • Not as necessary as you think
  • If you can deal with lifetimes...
  • Stack allocation > all

Demo?

meta.

Cool Rust stuff

  • Piston - game libraries
  • Rust-Postgres - great macro usage
  • Bindings to like any C library! Free FFI

Text

Thanks!!!

  • sinistersnare @ gmail
  • questions?!

The Rust Programming Language

By Davis Silverman

The Rust Programming Language

  • 3,696