Rust intro

(for non-Rust Developers)

OSCON 2017 - #OSCON

Hi!

  • Computer Engineer
  • Programming
  • Electronics
  • Math <3 <3
  • Physics
  • Lego
  • Meetups
  • Animals
  • Coffee
  • Pokémon
  • GIFs

#oscon @hannelita

OSS Projects:

  • https://github.com/hannelita/neo4j-cassandra-connector
  • https://github.com/hannelita/neo4j_doc_manager

 

Disclaimer

This is a session about Rust Features :)

Disclaimer

This is not a Rust intro tutorial

Some theory

Some subjects that may cause discussion. Views are on my own.

GIFs :)

Disclaimer

There are some references for introductory Rust Content

Language peace <3

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

What is Rust?

'Rust is a general purpose programming language, compiled, strong and static typed, sponsored by Mozilla Research. It is designed to be a "safe, concurrent, practical language", supporting functional and imperative-procedural paradigms.'

https://en.wikipedia.org/wiki/Rust_(programming_language)#cite_note-FAQ_-_The_Rust_Project-10

#oscon @hannelita

We all know Rust now

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Embedded systems

Sometimes they are so restrictive that you can't use Java.

Which language do you choose?

Source - http://www.diva-portal.org/smash/get/diva2:215157/FULLTEXT01

#oscon @hannelita

C and C++

#oscon @hannelita

C and C++

  • It's hard to debug
  • It can be difficult to maintain the code
  • Manual memory allocation

It may be inconvenient.

#oscon @hannelita

What are we looking for in terms of language?

#oscon @hannelita

Good choices

  • No manual memory management
  • Strong and Static Typed
  • Compiled
  • Fast
  • Reduce number of runtime errors
  • Active community
  • Good amount of frameworks and libraries
  • Open Source

#oscon @hannelita

Meet Rust!

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Quick view at Rust (FizzBuzz)

fn main() {
    
}
source: http://rustbyexample.com/fn.html

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
   fizzbuzz_to(n

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {




}

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {

    }
}

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
  fizzbuzz(n

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){





}

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){







}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }

Macros

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){







}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
fn is_divisible_by

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){







}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
fn is_divisible_by(lhs: u32, 
    rhs: u32)

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){







}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
fn is_divisible_by(lhs: u32, 
    rhs: u32) -> bool {





}

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){







}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
fn is_divisible_by(lhs: u32, 
    rhs: u32) -> bool {
    if rhs == 0 {
        return false;
    }
    lhs % rhs == 0

}

Limited type inference. Explicit type declaration for function parameters and return.

(same as in Java)

Quick view at Rust

fn main() {
    fizzbuzz_to(100);
}

fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
    if rhs == 0 {
        return false;
    }
    lhs % rhs == 0
}

fn fizzbuzz(n: u32) -> () {
    if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
}

fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
source: http://rustbyexample.com/fn.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    
}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Immutability by default

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;

    let mut mutable_binding = 1;
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;

    let mut mutable_binding = 1;
    mutable_binding += 1;
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust

fn main() {
    let my_binding = 1;
    my_binding += 1;

    let mut mutable_binding = 1;
    mutable_binding += 1;
    //^now it works! 
    

}
source: http://rustbyexample.com/variable_bindings/mut.html

Quick view at Rust




fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    







}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    






}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    





}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: 





}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        





}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)     // All natural numbers squared
             



}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..upper).map(|n| n * n)  //All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             



}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             


}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             .fold(0, |sum, i| sum + i); // Sum them
    println!("result: {}",
          sum_of_squared_odd_numbers);
}
source: http://rustbyexample.com/fn/hof.html

Quick view at Rust

fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             .fold(0, |sum, i| sum + i); // Sum them
    println!("result: {}",
          sum_of_squared_odd_numbers);
}
source: http://rustbyexample.com/fn/hof.html

High Order Functions

Other features - Tuples, Enums, Structs, Traits.

#oscon @hannelita

Rust - features

  • Memory safe, data race free
  • A compiler that blocks lots of runtime errors
  • Interface with C/C++
  • Generics
  • Polymorphism 
  • By Mozilla and an amazing community

#oscon @hannelita

Rust - it meets the requirements

  • No manual memory management √
  • Strong and Static Typed √
  • Compiled √
  • Fast √
  • Reduce number of runtime errors √
  • Active community √
  • Good amount of frameworks and libraries √
  • Open Source √

Bonus

  • About the same level of verbosity as Java :)
  • Rust Compiler is also verbose to explain the errors to you

#oscon @hannelita

More about Rust

  • No VM
  • No GC
  • No manual malloc/free
  • No seg faults

#oscon @hannelita

#oscon @hannelita

How do we achieve the 'No Seg Faults' feature?

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Variable bindings own the values in Rust

fn foo() {
    let v = vec![1, 2, 3];
    


}

#oscon @hannelita

Variable bindings own the values in Rust

fn foo() {
    let v = vec![1, 2, 3];
    let v2 = v;

}

#oscon @hannelita

Variable bindings own the values in Rust

fn foo() {
    let v = vec![1, 2, 3];
    let v2 = v;

    
}
Rust compiler says:"error: use of moved value: `v`
println!("v[0] is: {}", v[0]);"

What?

#oscon @hannelita

It may sound unpractical, but by having this model, Rust prevents several memory errors.

#oscon @hannelita

What happens if I REALLY want to share a reference?

fn main() {
    






    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);

}

Borrowing

#oscon @hannelita

Get 2 vectors and sum their values 

fn main() {


    fn vect_reduce



    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);
}

Borrowing

Get 2 vectors and sum their values 

#oscon @hannelita

fn main() {
    


    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>)    {


        
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);
}

Borrowing

Get 2 vectors and sum their values 

#oscon @hannelita

fn main() {
    


    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {


        
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);
}

Borrowing

Get 2 vectors and sum their values 

#oscon @hannelita

fn main() {
    


    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);
}

Borrowing

Get 2 vectors and sum their values 

#oscon @hannelita

fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);    
   // more code
}

Borrowing

#oscon @hannelita

Get 2 vectors and sum their values 

fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce( v1,  v2);
    //more code
}

Borrowing

I need to borrow the vectors to the function

if I use the variables again!

#oscon @hannelita

Get 2 vectors and sum their values 

fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce(&v1, &v2);
    //more code
}

Borrowing

I need to borrow the vectors to the function

if I use the variables again!

#oscon @hannelita

Get 2 vectors and sum their values 

fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce(&v1, &v2);
}

Borrowing

Also on the function

args:

#oscon @hannelita

Get 2 vectors and sum their values 

fn main() {
    fn sum_vec(v: &Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }

    fn vect_reduce(v1: &Vec<i32>, v2: &Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];

    let answer = vect_reduce(&v1, &v2);
}

Borrowing

Also on the function

args:

#oscon @hannelita

Get 2 vectors and sum their values 

Rust allows you to share some references with a feature called 'borrowing'

#oscon @hannelita

It is similar to Read-Writers lock

let v1 = vec![1, 2, 3];

Reader

Reader

Reader

v1, what is 

your value?

v1, what is 

your value?

v1, what is 

your value?

It is similar to Read-Writers lock

let v1 = vec![1, 2, 3];

Reader

Reader

Reader

v1, what is 

your value?

v1, what is 

your value?

v1, what is 

your value?

Writer

It is similar to Read-Writers lock

let v1 = vec![1, 2, 3];

Reader

Reader

Reader

v1, what is 

your value?

v1, what is 

your value?

v1, what is 

your value?

Writer

Readers, GET OUT OF HERE.

It is similar to Read-Writers lock

let mut v1 = vec![1, 2, 3];

Writer

Writers, GET OUT OF HERE.

It is similar to Read-Writers lock

let mut v1 = vec![1, 2, 3];

Writer

I AM EXCLUSIVE MHWAHUAAH

It is similar to Read-Writers lock

let mut v1 = vec![1, 2, 3];

Writer

Writers, GET OUT OF HERE.

If v1 is mut, the writer can change the vector value.

It is similar to Read-Writers lock

  • Many readers at once OR a single writer with exclusive access
  • Read only does not require exclusive access
  • Exclusive access does not allow other readers 
(More info: https://users.cs.duke.edu/~chase/cps210-archive/slides/moresync6.pdf )

Rust uses a similar model at compile time.

It is similar to Read-Writers lock

  • Many readers at once OR a single writer with exclusive access
  • Read only does not require exclusive access
  • Exclusive access does not allow other readers 

Rust uses a similar model at compile time.

T: Base type; owns a value

&T: Shared reader

&mut T: Exclusive writer

(Note: I am not considering another Rust feature called Copy)

It is similar to Read-Writers lock

  • Many readers at once OR a single writer with exclusive access
  • Read only do not require exclusive access
  • Exclusive access do not allow other readers 

Rust uses a similar model at compile time.

T: Base type; owns a value

&T: Shared reader

&mut T: Exclusive writer

(Note: I am not considering another Rust feature called Copy)

Immutable reference

Mutable reference

Transfering ownership

fn main() {
    let immutable_box = Box::new(5u32);
    





}

Transfering ownership

fn main() {
    let immutable_box = Box::new(5u32);
    // *Move* the box, changing the ownership 
    // (and mutability)


    


}

Transfering ownership

fn main() {
    let immutable_box = Box::new(5u32);
    // *Move* the box, changing the ownership 
    // (and mutability)
    let mut mutable_box = immutable_box;
    


}

Transfering ownership

fn main() {
    let immutable_box = Box::new(5u32);
    // *Move* the box, changing the ownership 
    // (and mutability)
    let mut mutable_box = immutable_box;
    // Modify the contents of the box
    *mutable_box = 4;

}

Transfering ownership

fn main() {
    let immutable_box = Box::new(5u32);
    // *Move* the box, changing the ownership 
    // (and mutability)
    let mut mutable_box = immutable_box;
    // Modify the contents of the box
    *mutable_box = 4;
    // IT WORKS!!! 
   

}
Note - * means you got a reference. You need to dereference it before you can do anything with it.

About exclusive writers

fn main() {
    let mut mutable_box = Box::new(5u32);

    




}

About exclusive writers

fn main() {
    let mut mutable_box = Box::new(5u32);

    // *Move* the box, changing the ownership
    let immutable_box = &mutable_box;





}

About exclusive writers

fn main() {
    let mut mutable_box = Box::new(5u32);

    // *Move* the box, changing the ownership
    let immutable_box = &mutable_box;


    // Modify the contents of the box
    *immutable_box = Box::new(4u32);



}

About exclusive writers

fn main() {
    let mut mutable_box = Box::new(5u32);

    // *Move* the box, changing the ownership
    let immutable_box = &mutable_box;


    // Modify the contents of the box
    *immutable_box = Box::new(4u32);



}

About exclusive writers

fn main() {
    let mut mutable_box = Box::new(5u32);

    // *Move* the box, changing the ownership
    let immutable_box = &mutable_box;


    // Modify the contents of the box
    *immutable_box = Box::new(4u32);



}

Top issues that borrowing prevents:

  • Iterator invalidation
  • Data race problems
  • Use after free

#oscon @hannelita

BTW, how do I free a variable in Rust? Since there is no GC, how should I clean up the memory?

#oscon @hannelita

Also, I could easily mess up with borrowing by freeing a variable that I lent to a function.

#oscon @hannelita

#oscon @hannelita

You don't have to handle that manually. At least, not explicitly.

#oscon @hannelita

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

In Rust, every reference has some lifetime associated with it.

fn lifetimes() {

    let a1 = vec![1, 2, 3]; //                 +
                                               |
                                               |
                                               |
                                               |
                                               |
                                              'a1
                                               |
}  

#oscon @hannelita

In Rust, every reference has some lifetime associated with it.

fn lifetimes() {

    let a1 = vec![1, 2, 3]; //                 +
                                               |
                                               |
                                               |
                                               |
                                               |
                                              'a1
                                               |
}  

#oscon @hannelita

In Rust, every reference has some lifetime associated with it.

fn lifetimes() {

    let a1 = vec![1, 2, 3]; //                 +
    let a2 = vec![4, 5, 6]; //            +    |
                            //            |    |
                                          |    |
                                          |    |
                                          |    |    
                                         'a2  'a1                                          

}  

#oscon @hannelita

In Rust, every reference has some lifetime associated with it.

fn lifetimes() {

    let a1 = vec![1, 2, 3]; //                 +
    let a2 = vec![4, 5, 6]; //            +    |
                            //            |    |
    let b1 = &a1;           //       +    |    |
    let b2 = &a2;           //  +    |    |    |
    foo(b1);                //  |    |    |    |
    foo(b2);                // 'b2  'b1  'a2  'a1
                            //  |    |    |    |
}  

#oscon @hannelita

You can explicit lifetimes in Rust

fn explicit_lifetime<'a>(x: &'a i32) {
}

Or even multiple lifetimes:

fn multiple_lifetimes<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
}

#oscon @hannelita

By the end of a lifetime, a variable is free.

#oscon @hannelita

  • GC is not necessary
  • Another mechanism to avoid dangling pointers 
  • No manual malloc nor free

Top issues that lifetime system prevents:

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Rust has a good Generics resource, with Traits and Closures

http://huonw.github.io/blog/2015/05/finding-closure-in-rust/

#oscon @hannelita

Comparison - Other languages and Rust Features

#oscon @hannelita

Classes

public class MyClass { 
    private in number = 42;
    private MyOtherClass c =
      new MyOtherClass();


    public int count() {
      ..
    }
}
struct MyClass {
    number: i32,
    other: MyOtherClass,
}

impl MyClass {
    fn myMethodCountHere(&self) -> i32 {
        ...
    }
}

Primitive types

Primitive types

#oscon @hannelita

Classes

class MyClass {
    int width, height;
  public:
    void set_values (int,int);
    int area() {return width*height;}
};
struct MyClass {
    number: i32,
    other: MyOtherClass,
}

impl MyClass {
    fn myMethodCountHere(&self) -> i32 {
        ...
    }
}

#oscon @hannelita

C++

Interfaces

public interface MyInterface {

	void someMethod();
	
	default void someDefault(String str){
		//implementation
	}

}
trait Animal {
    fn noise(&self) -> &'static str;
    fn talk(&self) {
        println!("I do not talk to humans");
    }
}

struct Horse { breed: &'static str }

impl Animal for Horse {
  fn noise(&self) -> &'static str {
    "neigh!"
    // I can't mimic horse sounds
  }

  fn talk(&self) {
      println!("{}!!!!", self.noise());
  }
}

impl Horse {
  fn move(&self) {
    //impl
  }
}

#oscon @hannelita

Generics

public class MyGeneric<T> {
  //impl
}

public class NotGeneric {
  public static <T extends Comparable<T>> T maximum(T x, T y) {
    //awesome
  }
} 
  
trait Traverse<I> {
  // methods
}

struct Bag<T> {
  //struct
}

impl<T> Bag<T> {
    //impl
}

#oscon @hannelita

Rust Generics

fn general_method<T: MyTrait>(t: T) { ... }

fn general_method<T: MyTrait + AnotherTrait + SomeRandomTrait>(t: T)

(Trait bounds: use it for the good and for the evil)

#oscon @hannelita

Rust looks great! Is it always safe?

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Rust is pretty specially because its memory model (ownership, borrowing, lifetimes)

#oscon @hannelita

You can call C/C++ functions from Rust. But C/C++ is not safe.

#oscon @hannelita

unsafe

fn main() {
    let u: &[u8] = &[49, 50, 51];

    unsafe {
        assert!(u == std::mem::transmute::<&str, &[u8]>("123"));
    }
}

#oscon @hannelita

Encapsulate unsafe calls inside safe functions.

#oscon @hannelita

So, is Rust perfect?

#oscon @hannelita

Agenda

  • What is Rust?
  • Why is Rust interesting?
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • Feature Comparison
  • The sense of safety
  • Rust downsides

#oscon @hannelita

Top Rust complaints

  • Learning curve
  • Lots of new concepts
  • Pretty new language

#oscon @hannelita

Top Rust complaints

  • Learning curve
  • Lots of new concepts
  • Pretty new language

Top Rust responses to these problems

  • Great docs and learning resources
  • The community is active and willing to help
  • The community is building lots of tools and libraries

#oscon @hannelita

Bonus #1:

How can you describe Rust type system?

#oscon @hannelita

Answer: Somewhat static, strongly typed. There is a huge research project to describe Rust type system

https://www.ralfj.de/blog/2015/10/12/formalizing-rust.html

#oscon @hannelita

Bonus #2: Performance

source: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=java

#oscon @hannelita

Bonus #3:

Free GIF! 

Bonus #4:

Try it now!

References

  • https://www.youtube.com/watch?v=Q7lQCgnNWU0
  • https://www.quora.com/Why-do-programming-languages-use-type-systems
  • http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html
  • http://lucacardelli.name/papers/typesystems.pdf
  • https://www.ralfj.de/blog/2015/10/12/formalizing-rust.html
  • http://jadpole.github.io/rust/type-system
  • https://wiki.haskell.org/Typing
  • https://gist.github.com/Kimundi/8391398
  • https://www.smashingmagazine.com/2013/04/introduction-to-programming-type-systems/
  • http://pcwalton.github.io/blog/2012/08/08/a-gentle-introduction-to-traits-in-rust/
  • https://llogiq.github.io/2016/02/28/java-rust.html

References - Rust Intro

  • https://doc.rust-lang.org/book/
  • https://doc.rust-lang.org/reference.html
  • https://doc.rust-lang.org/nomicon/
  • Rust And Pokémons -                              http://slides.com/hannelitavante-hannelita/rust-and-pokmons-en#/
  • Rust Type System - http://slides.com/hannelitavante-hannelita/rust-type-system-pybr12#/ (Python Brasil 2016 closing keynote)

Special Thanks

  • Rust Community - https://www.meetup.com/Rust-Sao-Paulo-Meetup/ and @bltavares
  • B.C., for the constant review
  • OSCON Team

Thank you! :)

Questions?

 

hannelita@gmail.com

@hannelita

Rust Intro (for non-Rust developers) - OSCON 2017

By Hanneli Tavante (hannelita)

Rust Intro (for non-Rust developers) - OSCON 2017

  • 4,434