rust-intro-presentation



rust-intro-presentation

0 0


rust-intro-presentation

Slide deck intro presentation about the Rust programming language

On Github olsonjeffery / rust-intro-presentation

The Rust Programming

Language

(a safe, concurrent, practical language)

Jeff Olson | http://olsonjeffery.github.io | @olsonjeffery

olsonjeffery/rust-intro-presentationhttp://olsonjeffery.github.io/rust-intro-presentation

Why Rust?

  • Safe
  • Concurrent
  • Practical

Some trivia

Modelling Data

enum Nation {
    Austria,
    England,
    France,
    Germany,
    Italy,
    Russia,
    Turkey
}
            

Modelling Data

enum ApplicationStatus {
    NotBegan,
    Pending(~ApplicationData),
    Approved(uint),
    Rejected(RejectionReason)
}
            

Modelling Data

match app_status {
    Pending(input) => process(input),
    Rejected(reason) => notify_of_rejection(reason),
    Approved(id) => {
        let user = get_user(id)
    },
    _ => {}
}
            

structs: C-compatible memory layout

traits: static/dynamic dispatch

struct Foo {
    baz: int
}
struct Bar {
    froboz: int
}
trait Contrived {
    fn gimme(&self) -> int;
}
impl Contrived for Foo {
    fn gimme(&self) -> int { self.baz }
}
impl Contrived for Bar {
    fn gimme(&self) -> int { self.froboz }
}
fn good_times<T: Contrived>(input: &T) {
    printn!("oohhhhhh yeeaah {}", input.gimme());
}
fn main() {
    let one = Foo { baz: 1 };
    let forty_two = Bar { froboz: 42 };
    // static dispatch
    good_times(one);
    good_times(forty_two);
}

traits: static/dynamic dispatch

fn main() {
    let one = Foo { baz: 1 };
    let forty_two = Bar { froboz: 42 };
    let list = [&one as &Contrived, &forty_two as &Contrived];
    for x in list {
        // dynamic dispatch
        println!("oooooh nooooo! {}", x.gimme());
    }
}

Memory

let foo = Bar::new();  // lives on the stack
let foo = &foo;        // reference to a value on the stack
let foo = ~Bar::new(); // lives on exchange heap
let foo = @Bar::new(); // lives in per-task heap (currently)

Memory (arrays of data)

let data = ~[1, 2, 3];          // fixed-size, allocated on the heap
let mut data = ~[];             // dynamic-size, lives on the heap
                                // aka "the growable vec"
data.push(1);
// ...
data.push(n);
let data = [1, 2, 3];           // fixed-size, on the stack
let mut data = [0u8, .. 65792]; // fixed-size, on the stack
let ptr = &data;
unsafe {
    some_c_library_call(ptr);   // transmutes to *u8
                                // C-compatible w/ char*
}

Quick aside on mutability

struct Blah {
    priv good_to_go: bool,
    could_be: int
}
impl Blah {
    fn new() -> Blah {
        Blah {
  good_to_go: true,
  could_be: 1
        }
    }
}
let mut whatevs = Blah::new();
whatevs.could_be = 134346;  // we'll tolerate this
whatevs.good_to_go = false; // NOPE

Ownership

struct Bar {
    state: int
}
impl Drop for Bar {
    fn drop(&mut self) {
        // cleanup happens here..
    }
}
fn foo(input: Bar) {
    println!("How you doin? {}", in.state);
    // input is free'd after this
}
fn main() {
    let bar: Bar = some_constructor_fn();
    foo(bar); // bar has been "moved" into foo()'s scope
    if bar.state == 0 { // BZZT! WRONG! compiler error
        // ...
    }
}

Ownership, again

fn foo(input: &Bar) { // we get a reference, instead
    in.state += 1; // nope. can't mutate this.
    println!("How you doin? {}", in.state);
}
fn main() {
    let bar: Bar = some_constructor_fn();
    foo(bar); // bar has been "moved" into foo()'s scope
    if bar.state == 0 { // we're allowed to do this, now
        // ...
    }
}

Ownership, one more time

fn foo(input: &mut Bar) { // we get a reference, instead
    in.state += 1; // ok. now we can do it.
    println!("Hit me {} more time", in.state);
}
fn main() {
    let bar = Bar(0);
    foo(bar); // bar has been "moved" into foo()'s scope
    if bar.state == 1 { // will be true
        // ...
    }
}

Lifetimes

fn foo(input: &'a int) { // 'a is the lifetime of the caller
    // lifetime c
}
fn main() {
    // lifetime a
    let some_val = 1;
    let bar = &some_val // has a lifetime delimited by this
    if true {
        // lifetime b
        foo(bar);
    }
}

Tasks

use task::spawn;
use comm::oneshot;

fn main() {
    let (port, chan) = oneshot();
    do spawn {
        chan.send(bool);
    }
    let v = port.recv();
}

Schedulers

use task::spawn_sched;
use comm::{stream, SharedChan};

fn main() {
    let mut sammiches = ~[];
    let (port, chan) = stream();
    let chan = SharedChan::new(chan);
    do 5.times {
        do spawn_sched {
            chan.send(parallel_sandwich_production());
        }
    }
    do 5.times {
        sammiches.push(port.recv());
    }
}

I/O

use std::rt::io::file::{FileInfo, FileStream};
use std::path::Path;
use std::rt::io::support::PathLike;
use std::rt::io::{FileMode, FileAccess};

fn main() {
    let foo = Path("/some/file/path.txt");
    let stream = foo.open_stream(Create, ReadWrite);
    let mut buf = [0u8, 65792];
    stream.read(buf);
}

Programming In The Large

Test framework

#[test]
fn some_test_for_whatever() {
    assert!(true);
}
fn another_one() {
    assert!(false);
}
> rustc --test some_code.rs
> ./some_code another

Modules

./main.rs
./some_mod.rs
./another_mod/mod.rs
./another_mod/more.rs
use some_mod;
use another_mod::more;
extern mod some_linked_library

mod some_mod;
mod another_mod;
mod locally_nested {
    fn magic() {}
}

fn main() {
    some_mod::magic();
    another_mod::more::magic();
    locally_nested::magic();
}
> rustc main.rs # might need more info to link properly, of course

The Rust Community

@rustlang

https://mail.mozilla.org/listinfo/rust-dev

http://reddit.com/r/rust

#rust on irc.mozilla.org

Thank You

Jeff Olson | http://olsonjeffery.github.io | @olsonjeffery