Pro Yearly is on sale from $80 to $50! »

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.

181de1fb11dffe39774f3e2e23cda3b6?s=128

Armin Ronacher

November 17, 2012
Tweet

Transcript

  1. Rust from Python & Ruby

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

  3. What is Rust?

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

  5. UNDER CONSTRUCTION

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

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

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

    %s!", *name)); } }
  9. fn main() { let s = [1, 2, 3, 4].map(|x|

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

    (x * x).to_str()); for s.each |&item| { io::println(item); } } Soon TM
  11. fn main() { let x = 42; let y =

    &x; let &z = y; io::println(fmt!("%d", z + z)); }
  12. $ cat hello.rs fn main() { io::println("Hello World!"); } $

    rustc -g hello.rs $ ./hello Hello World! Compile that
  13. In a Nutshell

  14. ✤ immutable by default ✤ static, algebraic, locally inferred types

    ✤ no dangling pointers, no overflows ✤ lightweight green tasks ✤ ahead-of-time compiled ✤ C compatible
  15. -FUTMPPLDMPTFS

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

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

    true }); }
  18. Expressions

  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 ] */
  20. Traits and Implementations

  21. trait LengthPrintable { fn print_length(); }

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

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

  24. Memory Ownership

  25. fn main() { let name = ~"Peter"; let new_name =

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

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

    move name; io::println(fmt!("Hello %s!", new_name)); } That compiles!
  28. Not Null (algebraic data types)

  29. def first_larger(seq, x): for item in seq: if item >

    x: return x Where is the NULL?
  30. fn first_larger(seq: &[int], x: int) -> Option<int> { for seq.each

    |item| { if *item > x { return Some(*item); } } None }
  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" }); }
  32. Pattern Matching!

  33. Enums (better than C's)

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

  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) } } }
  36. fn main() { let p = Point; let c =

    Circle(4.0f); io::println(fmt!("p=%s, c=%s", p.to_str(), c.to_str())); }
  37. “Classes”

  38. struct Point { mut x: float, mut y: float, }

    impl Point { static fn new(x: float, y: float) -> Point { Point { x: x, y: y } } }
  39. impl Point : ToStr { pure fn to_str() -> ~str

    { fmt!("(%f, %f)", self.x, self.y) } }
  40. fn main() { let p = Point::new(0.0f, 0.0f); io::println(p.to_str()); }

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

  42. trait inheritance no data inheritance !

  43. Tasks

  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)); } } } }
  45. FFI

  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) } }
  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!")); }
  48. bindgen for the lazy:

  49. Dear god … Why?

  50. Why a new language?

  51. Hello Concurrency

  52. Why is concurrency messy?

  53. Q: Why are global variables bad? A: there is only

    one of them!
  54. Concurrency in web apps: What do you actually share?

  55. Memory Tracking Enables Cheap Message Passing

  56. Spaghetti Stacks

  57. The Problems with Rust

  58. strings not implicitly copyable

  59. ownership tracking not perfect yet

  60. generics are harder to implement

  61. Option<T> is a bit of a pain

  62. directly using C APIs is icky

  63. task scheduler oblivious of libuv

  64. incomplete / work in progress

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

    http:// reteam.net/