Rust Type System - Quick intro

Python Brasil - 2016 - #pybr12

Rust Type System - Quick intro

Python Brasil - 2016 - #pybr12

Slides em Português:

http://slides.com/hannelitavante-hannelita/rust-pybr12-pt-br#/

Hi!

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

#pybr12 @hannelita

Python projects:

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

 

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

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

How do you choose a programming language?

#pybr12 @hannelita

  • By company
  • By popularity
  • By team
  • By deadline to deliver a project
  • By project goal
  • By available tools
  • That was the only language I learned at school
  • Somebody told me I should use that
  • I really don't know

#pybr12 @hannelita

How often do you consider the following items when choosing a language?

  • Type System
  • Immutability
  • Avoidance to runtime errors
  • Paradigm
  • Verbosity
  • Memory management

#pybr12 @hannelita

Wait - what is a type system? 

Let's ask Wikipedia:

"In programming languages, a type system is a collection of rules that assign a property called type to various constructs a computer program consists of"

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

Wait - what is a type system? 

#pybr12 @hannelita

In all languages, even in Assembly, we have at least two components:

Data

Operations

Not all of the available operations make sense to all kinds of data.

#pybr12 @hannelita

If you use incompatible pieces of data for an operation, you will have a representation error

#pybr12 @hannelita

Programming languages use a type system to look at a program and determine if a representation error will happen or not

#pybr12 @hannelita

What are the possible strategies that a type system can use to handle representation errors?

#pybr12 @hannelita

Strategies

  • Generate a compile error
  • Perform a type check before run the code
  • Well defined error set
  • Unpredictable  runtime errors
  • Try implicit conversion
  • A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)
  • A compiler / interpreter generates code to keep track of the data

#pybr12 @hannelita

Strategies

  • Generate a compile error
  • Perform a type check before run the code
  • Well defined error set
  • Unpredictable  runtime errors
  • Try implicit conversion
  • A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)
  • A compiler / interpreter generates code to keep track of the data

"Strong"

"Weak"

"Static"

"Dynamic"

* Definitions are not exact on literature

Strategies

  • Generate a compile error
  • Perform a type check before run the code
  • Well defined error set
  • Unpredictable  runtime errors
  • Try implicit conversion
  • A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)
  • A compiler / interpreter generates code to keep track of the data

"Strong"

"Weak"

"Static"

"Dynamic"

  • Do nothing

"Untyped"

You don't have to choose only one alternative

Python: strong (the interpreter does not change the types) and dynamic type system (the interpreter keeps track of the variables)

#pybr12 @hannelita

One strategy to reduce runtime errors is adopting a static and strong type system

#pybr12 @hannelita

Java sort of fits at this description.

Java can be annoying due to GC

#pybr12 @hannelita

Use C or C++

No consensus about weak or strong type system.

#pybr12 @hannelita

Rust comes to rescue

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @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

#pybr12 @hannelita

Rust - features

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

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

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 n in 1..n + 1 {
        fizzbuzz(n);
    }
}
source: http://rustbyexample.com/fn.html

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

Macros

Quick view at Rust

fn main() {
    let _immutable_binding = 1;
    let mut mutable_binding = 1;
    println!("Before mutation: {}", mutable_binding);
    // Ok
    mutable_binding += 1;
    println!("After mutation: {}", mutable_binding);

    // Error!
    _immutable_binding += 1;
    // FIXME ^ Comment out this line
}
source: http://rustbyexample.com/variable_bindings/mut.html

Immutability by default

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 mut acc = 0;
    for n in 0.. {
        let n_squared = n * n;
        if n_squared >= upper {
            break;
        } else if is_odd(n_squared) {
            acc += n_squared;
        }
    }
    println!("imperative style: {}", acc);
    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!("functional style: {}", sum_of_squared_odd_numbers);
}
source: http://rustbyexample.com/fn/hof.html

High 

Order

Functions

Other features - Tuples, Enums, Structs, Traits.

#pybr12 @hannelita

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

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

Variable bindings own the values in Rust

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

    println!("v[0] is: {}", v[0]);
}

#pybr12 @hannelita

Variable bindings own the values in Rust

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

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

What?

#pybr12 @hannelita

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

#pybr12 @hannelita

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

#pybr12 @hannelita

fn main() {
    fn sum_vec(v: &Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn foo(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 = foo(&v1, &v2);
    println!("{}", answer);
}

Borrowing

&

#pybr12 @hannelita

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

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

About exclusive writers

fn main() {
    let mut x = 5;
    let y = &mut x;

    *y += 1;

    println!("{}", x);
}
Rust compiler says: "error: cannot borrow `x` as immutable because it is also borrowed as mutable println!("{}", x);"

Top issues that borrowing prevents:

  • Iterator invalidation
  • Data race problems
  • Use after free

#pybr12 @hannelita

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

#pybr12 @hannelita

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

#pybr12 @hannelita

#pybr12 @hannelita

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

#pybr12 @hannelita

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @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
                            //  |    |    |    |
}  

#pybr12 @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 {
}

#pybr12 @hannelita

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

#pybr12 @hannelita

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

Top issues that lifetime system prevents:

#pybr12 @hannelita

Okay, so is Rust always safe?

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

Rust is pretty safe not only because of borrowing and lifetimes

#pybr12 @hannelita

Rust has a good Generics resource, with Traits and Closures

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

#pybr12 @hannelita

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

#pybr12 @hannelita

unsafe

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

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

#pybr12 @hannelita

Explicit calls for unsafe.

#pybr12 @hannelita

So, is Rust perfect?

#pybr12 @hannelita

Agenda

  • Choosing a programming language
  • Quick intro about type systems
  • Why Rust can be interesting
  • Rust structure quick overview
  • Borrow
  • Lifetime
  • The sense of safety
  • Rust downsides

#pybr12 @hannelita

Top Rust complaints

  • Learning curve is not too fast
  • Lots of new concepts
  • Pretty new language

#pybr12 @hannelita

Top Rust complaints

  • Learning curve is not too fast
  • 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

#pybr12 @hannelita

Bonus #1: Final question -

How can you describe Rust type system?

#pybr12 @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

#pybr12 @hannelita

Bonus #2:

This topic about types is great! What are the next learning steps?

Answer: Lambda Calculus and Type Theory :)

#pybr12 @hannelita

http://slides.com/hannelitavante-hannelita/type-theory-101-35#/

Bonus #3:

Free GIF! 

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/

(Some of them are not too scientific)

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#/

Special Thanks

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

Thank you :)

Questions?

 

hannelita@gmail.com

@hannelita

Rust Type system

By Hanneli Tavante (hannelita)

Rust Type system

  • 2,201
Loading comments...

More from Hanneli Tavante (hannelita)