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

Rust. El lenguaje que reeplazará a C y C++

Rust. El lenguaje que reeplazará a C y C++

Roberto Perez

November 28, 2015
Tweet

More Decks by Roberto Perez

Other Decks in Programming

Transcript

  1. • Working @ Tokbox / Telefonica • Programming languages aficionado

    • Retrocomputing fan • Videogames enthusiast • 日本語学校生 Presentación
  2. c# c java ruby python rust c++ go swift groovy

    objective-c scala clojure Podria programarlo rapidamente
  3. c# c java ruby python rust c++ go swift groovy

    objective-c scala clojure Es multiplataforma (y su sdk)
  4. c# c java ruby python rust c++ go swift groovy

    objective-c scala clojure Tiene un sdk con muchas utilidades que me haran ser mas productivo
  5. Necesitamos que sea muy eficiente c# c java ruby python

    rust c++ go swift groovy objective-c scala clojure
  6. c# c java ruby python rust c++ go swift groovy

    objective-c scala clojure No tiene runtime ni garbage collector c# c java ruby python rust c++ go swift groovy objective-c scala clojure
  7. c# c java ruby python rust c++ go swift groovy

    objective-c scala clojure Tiene gestor de paquetes / dependencias integrado Me garantiza que no voy a meter la pata con la gestión de memoria Es un lenguaje moderno: tiene closures, destructuring, caracteristicas funcionales,... c# c java ruby python rust c++ go swift groovy objective-c scala clojure
  8. rust facts • Creado por Graydon Hoare (Mozilla) como un

    proyecto personal • Patrocinado por Mozilla en 2009 y con compilador hecho en rust en 2011 • 1.0 fue lanzado en 15 de mayo de 2015 • Lenguaje elegido para crear Servo, el futuro layout engine de Firefox. • Usa LLVM • Version estable actual (nov 2015): 1.4
  9. Agenda • Principios de diseño de rust • Memory safety

    • Modern Language • Structs • Traits • Generics • Concurrencia • Cargo • Conclusiones
  10. principios de diseño • system language ◦ código de bajo

    nivel ◦ portable ◦ sin garbage collector • enfocado en tres metas: ◦ velocidad ◦ seguridad ◦ concurrencia • poder ser embebido en otros lenguajes • sistema de tipos basado en traits • gestor de dependencias
  11. memory safety int main() { char str[] = "hola codemotion";

    char *p = (char *) malloc(strlen(str)); strcpy(p, str); } $ gcc holamundo.c -Wall 0 errors. 0 warnings. yay! $ ./a.out hola codemotion It works!
  12. memory safety • Basado en tiempo de compilación. “Zero cost

    abstraction” • Stack preferred allocation • Inmutabilidad by default • ownership • borrowing • lifetimes
  13. ownership, copy & move let v = vec![1, 2, 3];

    let v2 = v; println!("v2[0] is: {}", v2[0]); // OK println!("v[0] is: {}", v[0]); // Error! • v esta allocado en stack, pero su contenido en heap • Vec<> no implementa el trait Copy • v2 = v crea una copia del puntero
  14. ownership, copy & move let char1 = ‘a’; let char2

    = char1; println!("char1 is: {}", char1); • char implementa Clone / Copy, al igualarlo se copia
  15. ownership, copy & move fn func1(a: Vec<u32>) { } let

    a = vec![1,2]; let b = func1(a); println!("{:?}", a); // ERROR
  16. borrow fn func1(v: &Vec<i32>) { // ... } let v

    = vec![]; func1(&v); println!(“{:?}”, v); // OK! • & crea un nuevo binding de variable pero a la referencia del tipo
  17. borrow fn func1(v: &mut Vec<i32>) { v.push(4); } let mut

    v = vec![]; func1(&mut v); println!(“{:?}”, v); • Para crear referencias mutables, necesitamos especificar &mut
  18. borrow Las dos reglas mutuamente exclusivas del borrow: • Se

    pueden tener N referencias a una variable • Se puede tener solo una referencia mutable let mut a = vec![1,2]; let b = &a; let mut c = &mut a; // Error println!(“{:?}”, a);
  19. borrow • La vida de la variable a la que

    se referencia siempre tiene que ser mayor que la de la variable que referencia let x : &u32; { let y = 10; x = &y; } // Error, y sale fuera del scope aqui
  20. lifetimes • Es posible (y a veces necesario) especificar los

    tiempos de vida de algunas variables let x : &str; { let y : &'static str = "Hola Mundo"; x = y; } println!("{}", x); // OK!
  21. modern language ranges, destructuring fn main() { for i in

    1..101 { match i { n if n % 15 == 0 => print!("fizzbuzz "), n if n % 3 == 0 => print!("fizz "), n if n % 5 == 0 => print!("buzz "), n => print!("{} ", n) } } }
  22. modern language closures let duplicate = |i| i * 2;

    println!("{:?}", duplicate(5)); let counter = 3; let add_fix_counter = |i| i + counter; println!("{:?}", add_fix_counter(5));
  23. modern language closures let mut value = 5; let add_value

    = |i| i + value; println!("{}", add_value(30)); value = 10; // ERROR!, value ya ha sido borrowed println!("{}", add_value(30)); let mut greeting = vec![1,2,3]; { let mut a = |i| greeting.push(i); a(4) } println!("{:?}", greeting); // All right!
  24. modern language optional types • No hay “null” pointers en

    Rust, toda variable debe tener un valor if a.is_some() { println!("Has some"); } let mut range = 1..10; while let Some(index) = range.next() { println!("{}", index); } if let Some(b) = a { println!("{}", b); } else { println!("None!"); } let a : Option<u32> = Some(5);
  25. modern language functional heritage fn main() { fn apply<F :

    Fn(i32) -> i32>(f: F, val: i32) -> i32 { f(val) }; let sum_10 = |i| i + 10; println!("{}", apply(sum_10, 40)); } let f = (1..100). filter(|n| is_even(n)). map(|n| n * n). collect::<Vec<i32>>(); let sum = (1..100). filter(|n| is_even(n)). map(|n| n * n). fold(0, |sum ,n| sum + n);
  26. modern language iterators • Lazy iterators collect() fold() find() any()

    all() ... Consumers map() filter() take() take_while() ... Adapters for val in (1..100).filter(|n| is_even(n)) { println!("{}", val); }
  27. structs & impl #[derive(Debug)] struct Point { x: i32, y:

    i32 } impl Point { fn move_to(&self, dx: i32, dy: i32) -> Point { Point { x: self.x + dx, y: self.y + dy } } fn mut_move_to(&mut self, dx: i32, dy: i32) { self.x += dx; self.y += dy; } }
  28. traits impl fmt::Debug for Point { fn fmt(&self, f: &mut

    fmt::Formatter) -> fmt::Result { write!(f, "({}, {})", self.x, self.y) } } pub trait Debug { fn fmt(&self, &mut Formatter) -> Result<(), Error>; }
  29. a little taste on generics • Functions, structs, enums e

    incluso traits pueden tener parametros que definen tipos genericos fn print_debuggable<T: Debug>(val: T) { println!("{:?}", val); } fn print_debuggable<K: Debug, T: Debug + Clone>(val1: K, val2: T) { val2.clone(); println!("{:?}, {:?}", val1, val2); } fn print_debuggable<K, T>(val1: K, val2: T) where K: Debug, T: Debug + Clone {}
  30. concurrencia • Uso de threads nativos por el OS •

    std::sync [ Arc, Barrier, RwLock, Once, Mutex, CondVar, ...] • Canales de comunicación entre hilos let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel(); for id in 0..5 { let thread_tx = tx.clone(); thread::spawn(move || { thread_tx.send(id).unwrap(); }); } for _ in 0..5 { println!(rx.recv())); }
  31. cargo • gestor de paquetes • utilidad para construir, testear,

    crear proyectos Cargo.toml [package] name = "hello_world" version = "0.1.0" authors = ["Your Name <[email protected]>"] [dependencies] regex = "0.1.41" $ cargo new --bin sqltiny $ cargo build $ cargo run
  32. rust. there is more to come operator overloading macro_rules! compiler

    plugins rust doc associated types phantom types lifetime elision error handling unsafe move closures generics testing
  33. algunas conclusiones • Semántica y readability algo compleja (posiblemente al

    nivel de C++) • Lenguaje destinado a creación de software de alto rendimiento, sistemas operativos, game engines, web rendering engines (servo?) • Si no nos metemos con “unsafe” gran seguridad de que no la vamos a liar con uso incorrecto de la memoria. • Al ser posible ser llamado y llamar a módulos desarrollados en C/C++, es posible afrontar desarrollos reemplazando partes de nuestro sistema • Le falta una libreria de I/O asíncrono. gran debate en la comunidad
  34. mas conclusiones • Rust no es competidor de Go •

    Ser un frontend de LLVM le abre muchas puertas. • Funciona en Android / iOS • Poco a poco se ha ido estabilizando • C++ es su gran alternativa, aunque carece de cosas como la seguridad en la gestión de la memoria y aspectos “avanzados” del lenguaje (aunque se han ido incluyendo en C++11, C++14, C++17) • Swift??. Aun esta encerrado en Apple, pero si lo hacen opensource multiplataforma y su sdk también, puede ser otro gran competidor.