Slide 1

Slide 1 text

Rust. El lenguaje que reemplazará a C/C++ Roberto Pérez. codemotion 2015

Slide 2

Slide 2 text

● Working @ Tokbox / Telefonica ● Programming languages aficionado ● Retrocomputing fan ● Videogames enthusiast ● 日本語学校生 Presentación

Slide 3

Slide 3 text

¿Qué lenguaje debería elegir para construir sqltiny?

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Necesitamos que sea muy eficiente c# c java ruby python rust c++ go swift groovy objective-c scala clojure

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Agenda ● Principios de diseño de rust ● Memory safety ● Modern Language ● Structs ● Traits ● Generics ● Concurrencia ● Cargo ● Conclusiones

Slide 12

Slide 12 text

DISCLAIMER you are going to see a lot of rust source code

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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!

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

un momento..., no tan rápido

Slide 17

Slide 17 text

memory safety ● Basado en tiempo de compilación. “Zero cost abstraction” ● Stack preferred allocation ● Inmutabilidad by default ● ownership ● borrowing ● lifetimes

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

ownership, copy & move let char1 = ‘a’; let char2 = char1; println!("char1 is: {}", char1); ● char implementa Clone / Copy, al igualarlo se copia

Slide 20

Slide 20 text

ownership, copy & move fn func1(a: Vec) { } let a = vec![1,2]; let b = func1(a); println!("{:?}", a); // ERROR

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

borrow fn func1(v: &mut Vec) { v.push(4); } let mut v = vec![]; func1(&mut v); println!(“{:?}”, v); ● Para crear referencias mutables, necesitamos especificar &mut

Slide 23

Slide 23 text

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);

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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!

Slide 26

Slide 26 text

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) } } }

Slide 27

Slide 27 text

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));

Slide 28

Slide 28 text

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!

Slide 29

Slide 29 text

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 = Some(5);

Slide 30

Slide 30 text

modern language functional heritage fn main() { fn apply 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::>(); let sum = (1..100). filter(|n| is_even(n)). map(|n| n * n). fold(0, |sum ,n| sum + n);

Slide 31

Slide 31 text

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); }

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

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; } }

Slide 34

Slide 34 text

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>; }

Slide 35

Slide 35 text

a little taste on generics ● Functions, structs, enums e incluso traits pueden tener parametros que definen tipos genericos fn print_debuggable(val: T) { println!("{:?}", val); } fn print_debuggable(val1: K, val2: T) { val2.clone(); println!("{:?}, {:?}", val1, val2); } fn print_debuggable(val1: K, val2: T) where K: Debug, T: Debug + Clone {}

Slide 36

Slide 36 text

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, Receiver) = 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())); }

Slide 37

Slide 37 text

cargo ● gestor de paquetes ● utilidad para construir, testear, crear proyectos Cargo.toml [package] name = "hello_world" version = "0.1.0" authors = ["Your Name "] [dependencies] regex = "0.1.41" $ cargo new --bin sqltiny $ cargo build $ cargo run

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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.

Slide 41

Slide 41 text

ありがとうございます @hylian robj.perez@gmail.com