$30 off During Our Annual Pro Sale. View Details »

Rust from Python & Ruby

Rust from Python & Ruby

Introduction to Rust for people that use Python and Ruby. Notice that this is about a work in progress Rust around version 0.4. YMMV.

Armin Ronacher

November 17, 2012
Tweet

More Decks by Armin Ronacher

Other Decks in Programming

Transcript

  1. Rust
    from
    Python
    & Ruby

    View Slide

  2. Armin Ronacher
    @mitsuhiko
    Python Dude
    (with Ruby experience)

    View Slide

  3. What is Rust?

    View Slide

  4. Programming
    Language
    printf("Hello "
    "World!\n");

    View Slide

  5. UNDER CONSTRUCTION

    View Slide

  6. def main():
    for name in ["Peter", "Paul", "Mary"]:
    print "Hello %s!" % name

    View Slide

  7. def main
    ["Peter", "Paul", "Mary"].each do |name|
    puts "Hello %s!" % name
    end
    end

    View Slide

  8. fn main() {
    for ["Peter", "Paul", "Mary"].each |name| {
    io::println(fmt!("Hello %s!", *name));
    }
    }

    View Slide

  9. fn main() {
    let s = [1, 2, 3, 4].map(|x| (*x * *x).to_str());
    for s.each |item| {
    io::println(*item);
    }
    }

    View Slide

  10. fn main() {
    let s = [1, 2, 3, 4].map(|&x| (x * x).to_str());
    for s.each |&item| {
    io::println(item);
    }
    }
    Soon TM

    View Slide

  11. fn main() {
    let x = 42;
    let y = &x;
    let &z = y;
    io::println(fmt!("%d", z + z));
    }

    View Slide

  12. $ cat hello.rs
    fn main() {
    io::println("Hello World!");
    }
    $ rustc -g hello.rs
    $ ./hello
    Hello World!
    Compile that

    View Slide

  13. In a Nutshell

    View Slide

  14. ✤ immutable by default
    ✤ static, algebraic, locally inferred types
    ✤ no dangling pointers, no overflows
    ✤ lightweight green tasks
    ✤ ahead-of-time compiled
    ✤ C compatible

    View Slide

  15. -FUTMPPLDMPTFS

    View Slide

  16. fn main() {
    for ["Peter", "Paul", "Mary"].each |name| {
    io::println(fmt!("Hello %s!", *name));
    }
    }

    View Slide

  17. fn main() {
    ["Peter", "Paul", "Mary"].each(|name| {
    io::println(fmt!("Hello %s!", *name));
    true
    });
    }

    View Slide

  18. Expressions

    View Slide

  19. fn main() {
    let a = [1, 2, 3].map(|x| { *x; });
    let b = [1, 2, 3].map(|x| { *x });
    io::println(fmt!("a=%? b=%?", a, b));
    }
    /* a=~[ (), (), () ] b=~[ 1, 2, 3 ] */

    View Slide

  20. Traits and
    Implementations

    View Slide

  21. trait LengthPrintable {
    fn print_length();
    }

    View Slide

  22. impl &[T]: LengthPrintable {
    fn print_length() {
    io::println(fmt!("length = %u", self.len()));
    }
    }

    View Slide

  23. fn main() {
    ["Peter", "Paul", "Mary"].print_length();
    }

    View Slide

  24. Memory Ownership

    View Slide

  25. fn main() {
    let name = ~"Peter";
    let new_name = name;
    io::println(fmt!("Hello %s!", name));
    }
    Does not compile: string (currently) does not copy

    View Slide

  26. fn main() {
    let name = ~"Peter";
    let new_name = move name;
    io::println(fmt!("Hello %s!", name));
    }
    Does not compile: using moved-out value

    View Slide

  27. fn main() {
    let name = ~"Peter";
    let new_name = move name;
    io::println(fmt!("Hello %s!", new_name));
    }
    That compiles!

    View Slide

  28. Not Null
    (algebraic data types)

    View Slide

  29. def first_larger(seq, x):
    for item in seq:
    if item > x:
    return x
    Where is the NULL?

    View Slide

  30. fn first_larger(seq: &[int], x: int) -> Option {
    for seq.each |item| {
    if *item > x { return Some(*item); }
    }
    None
    }

    View Slide

  31. fn main() {
    let rv = first_larger([1, 2, 3, 4, 5], 3);
    io::println(match rv {
    Some(num) => fmt!("Found %d", num),
    None => ~"No number found"
    });
    }

    View Slide

  32. Pattern Matching!

    View Slide

  33. Enums
    (better than C's)

    View Slide

  34. enum Shape {
    Point,
    Circle(float),
    Rect(float, float)
    }

    View Slide

  35. impl Shape : ToStr {
    pure fn to_str() -> ~str {
    match self {
    Point => ~"point",
    Circle(r) => fmt!("circle of %f", r),
    Rect(w, h) => fmt!("rect of %f by %f", w, h)
    }
    }
    }

    View Slide

  36. fn main() {
    let p = Point;
    let c = Circle(4.0f);
    io::println(fmt!("p=%s, c=%s",
    p.to_str(), c.to_str()));
    }

    View Slide

  37. “Classes”

    View Slide

  38. struct Point {
    mut x: float,
    mut y: float,
    }
    impl Point {
    static fn new(x: float, y: float) -> Point {
    Point { x: x, y: y }
    }
    }

    View Slide

  39. impl Point : ToStr {
    pure fn to_str() -> ~str {
    fmt!("(%f, %f)", self.x, self.y)
    }
    }

    View Slide

  40. fn main() {
    let p = Point::new(0.0f, 0.0f);
    io::println(p.to_str());
    }

    View Slide

  41. Hold on a second!
    */)&3*5"/$& ?

    View Slide

  42. trait inheritance
    no data inheritance !

    View Slide

  43. Tasks

    View Slide

  44. fn main() {
    for ["Peter", "Paul", "Mary"].each |name| {
    let name = *name;
    do task::spawn {
    let v = rand::Rng().shuffle([1, 2, 3]);
    for v.each |num| {
    io::print(fmt!("%s says: '%d'\n",
    name, *num));
    }
    }
    }
    }

    View Slide

  45. FFI

    View Slide

  46. #[link_args="-lcrypto"]
    extern {
    fn SHA1(s: *u8, l: libc::c_uint, d: *u8) -> *u8;
    }
    fn sha1(data: &str) -> ~str {
    unsafe {
    let bytes = str::to_bytes(data);
    let mut buf = [0u8, ..20];
    SHA1(vec::raw::to_ptr(bytes),
    bytes.len() as libc::c_uint,
    vec::raw::to_ptr(buf));
    as_hex(buf)
    }
    }

    View Slide

  47. fn as_hex(data: &[u8]) -> ~str {
    let mut rv = ~"";
    for data.each |b| {
    rv += fmt!("%02x", *b as uint);
    }
    move rv
    }
    fn main() {
    io::println(sha1("Hello World!"));
    }

    View Slide

  48. bindgen
    for the lazy:

    View Slide

  49. Dear god …
    Why?

    View Slide

  50. Why a new language?

    View Slide

  51. Hello Concurrency

    View Slide

  52. Why is concurrency
    messy?

    View Slide

  53. Q: Why are global variables bad?
    A: there is only one of them!

    View Slide

  54. Concurrency in web apps:
    What do you actually share?

    View Slide

  55. Memory Tracking Enables
    Cheap Message Passing

    View Slide

  56. Spaghetti Stacks

    View Slide

  57. The Problems
    with Rust

    View Slide

  58. strings not implicitly copyable

    View Slide

  59. ownership tracking not perfect yet

    View Slide

  60. generics are harder to implement

    View Slide

  61. Option is a bit of a pain

    View Slide

  62. directly using C APIs is icky

    View Slide

  63. task scheduler oblivious of libuv

    View Slide

  64. incomplete / work in progress

    View Slide

  65. Q&A
    Thanks, now there is time for …
    @mitsuhiko
    http://lucumr.pocoo.org/
    http:// reteam.net/

    View Slide