24
Nicholas Matsakis Mozilla Research

IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Nicholas Matsakis!Mozilla Research

Page 2: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

2

Systems programming without the hasslecrashes!heisenbugs!fear

Parallel!

Page 3: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

3

C/C++: efficiency first!destructors memory layout smart pointers monomorphization

ML/Haskell: safety first!ADTs and pattern matching type inference no null pointers closures traits (typeclasses)

Research community!affine/ownership types region-based borrowing

Page 4: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

// sums all the positive values in `v` fn sum_pos(v: &[i32]) -> i32 { let mut sum = 0; for i in v.iter().filter(|i| **i > 0) { sum += *i; } sum }

High-level coding

4

Iterators.

Closures.

Page 5: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Assembly code

5

leaq (%rdi,%rsi,4), %rcx xorl %eax, %eax jmp .LBB5_1 .LBB5_3: addl %edx, %eax .align 16, 0x90 .LBB5_1: cmpq %rdi, %rcx je .LBB5_4 movl (%rdi), %edx addq $4, %rdi testl %edx, %edx jle .LBB5_1 jmp .LBB5_3 .LBB5_4: retq

Page 6: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn foo(v: &[i32]) -> i32 { v.iter() .filter(|i| **i > 0) .map(|i| *i) .sum() }

Higher-level coding

6

…generates the same assembly code.

Page 7: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Safe

7

fn this_wont_compile(v: &mut Vec<i32>) -> i32 { let mut sum = 0; for &i in v.iter() { sum += i; if i > 0 { v.push(0); } } sum }

error: cannot borrow `*v` as mutable because it is also borrowed as immutable if i > 0 { v.push(0); } ^ note: previous borrow of `*v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*v` until the borrow ends for &i in v.iter() { ^

Might free underlying buffer.

Page 8: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); parallel::join( || parallel_qsort(less), || parallel_qsort(greater) ); }

Parallel

8

Sort left and right in parallel.

Page 9: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); parallel::join( || parallel_qsort(less), || parallel_qsort(less) ); }

Parallel… and safe

9

error: closure requires unique access to `less` but it is already borrowed || parallel_qsort(less) ^~~~~~~~~~~~~~~~~~~~~~~

Data race.

Page 10: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Multiparadigm

10

message-passing

mutable shared memory

functional

imperative

Page 11: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Open and welcoming

Rust has been open source from the beginning. !

Open governance model based on public RFCs. !

We have an active, amazing community.

11

Page 12: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Whither Safety?

12https://www.flickr.com/photos/langtind/2217639550/in/photostream/

Page 13: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

13

It’s a dangling pointer!

No, it’s a data race!

No, it’s a double free!

Simultaneous Aliasing and

Mutation

No, it’s iterator

invalidation!

Page 14: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

The Big Idea

Ownership and borrowing:!!1. All memory has a clear owner. 2. Others can borrow from the owner. 3. Owner cannot free or mutate the

memory while it is borrowed.

14

Page 15: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn sum(v: Vec<i32>) -> i32 { let mut s = 0; for i in 0..v.len() { s += v[i]; } s }

Ownership 15

fn main() { let mut v = vec![…]; let sum = sum(v); println!(“{:?}”, sum); … }

Take ownership of a Vec<i32>

Give the vector to sum()

Page 16: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn sum(v: Vec<i32>) -> i32 { let mut s = 0; for i in 0..v.len() { s += v[i]; } s }

fn main() { let mut v = vec![…]; let sum = sum(v); println!(“{:?}”, sum); … } v[0] += 1;

Compiler enforces moves

16

error: use of moved value: `v` v[0] += 1; ^ note: `v` moved here because it has type `Vec<i32>`, which is non-copyable let sum = sum(v); ^

Page 17: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Two birds, one stone

17

Ownership solves: - Memory management - Message passing - Strong encapsulation

Page 18: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn main() { let mut v = vec![…]; let sum = sum(&v); println!(“{:?}”, sum); v[0] += 1; }

fn sum(v: &Vec<i32>) -> i32 { let mut s = 0; for i in 0..v.len() { s += v[i]; } s }

Shared borrow

Take a reference to a Vec<i32>

18

Lend the vector

Page 19: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn main() { let mut v = vec![…]; sum(&mut v); v[0] += 1; }

fn sum(v: &mut Vec<i32>) { let mut s = 0; for i in 0..v.len() { s += v[i]; v[i] = s; } }

Mutable borrow

Take a mutable reference to a Vec<i32>

19

Lend the vector mutably

Page 20: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn example() { let mut names = Vec::new(); names.push(..); names.push(..); let name = &names[1]; names.push(..); print(name); }

names

data

length

capacity

“brson”

“pcwalton”

name

“brson”

“pcwalton”

“acrichto”

Sharing: more than one pointer to same memory.

Dangling pointer: pointer to freed memory.

Mutating the vector freed old contents.

20

Page 21: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

Rust solution

21

Compile-time read-write-lock:!!Creating a shared reference to X “read locks” X. - Other readers OK. - No writers. - Lock lasts until reference goes out of scope. !Creating a mutable reference to X “writes locks” X. - No other readers or writers. - Lock lasts until reference goes out of scope.

Never have a reader/writer at same time.

Page 22: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn example() { let mut names = Vec::new(); names.push(“brson”); names.push(“pcwalton”); let name = &names[1]; names.push(“acrichto”); println!(“{:?}”, name); }

Borrow “locks” `names` until `name` goes out of scopeError: cannot mutate

`names` while borrowed

22http://is.gd/jeKW1E

Page 23: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

fn parallel_qsort(vec: &mut [int]) { if vec.len() <= 1 { return; } let pivot = vec[random(vec.len())]; let mid = vec.partition(vec, pivot); let (less, greater) = vec.split_at_mut(mid); parallel::join( || parallel_qsort(less), || parallel_qsort(less) ); }

Back to qsort

23

Creating closure borrows `less`

mutably

This closure also needs a

mutable borrow

Page 24: IBM PL Day v2smart pointers monomorphization ML/Haskell: safety first! ADTs and pattern matching type inference no null pointers closures traits (typeclasses) Research community!

24

Hack without fear!