Rust for Everyone
=================
- talk based on Rust for Everyone! by Will Crichton https://www.youtube.com/watch?v=R0dP-QR5wQo
---
Rust is
-------
# "A language empowering everyone to build reliable and efficient software."
Systems programming
Functional programming
*(low-level machine code)*
*(high-level expressiveness)*
---
Rust is
-------
## "A language empowering everyone to build reliable and efficient software."
everything you don't know about
everything you don't know about
Systems programming
Functional programming
numeric types, memory, pointers
higher-order functions, algebraic data types, typestate
---
# How can we empower more people to learn and use Rust?
---
# How can we systematically empower more people to learn and use Rust?
---
An Ownership Visualizer
=======================
---
Example of memory violation in C++
----------------------------------
```c++
vector v = {1, 2, 3}; // <--
int *num = &v[2];
v.push_back(4);
cout << *num << endl;
```
```
stack heap
+-----+---+ +-------+
| v | o-|------> | 1 2 3 |
+-----+---+ +-------+
```
---
Example of memory violation in C++
----------------------------------
```c++
vector v = {1, 2, 3};
int *num = &v[2]; // <--
v.push_back(4);
cout << *num << endl;
```
```
stack heap
+-----+---+ +-------+
| v | o-|------> | 1 2 3 |
+-----+---+ +-----^-+
| num | o-|--------------+
+-----+---+
```
---
Example of memory violation in C++
----------------------------------
```c++
vector v = {1, 2, 3};
int *num = &v[2];
v.push_back(4); // <--
cout << *num << endl;
```
```
stack heap
+-----+---+ +---------+
| v | o-|------> | 1 2 3 4 |
+-----+---+ +---------+
| num | ? |
+-----+---+
```
---
Example of memory violation in C++
----------------------------------
```c++
vector v = {1, 2, 3};
int *num = &v[2];
v.push_back(4);
cout << *num << endl; // <--
```
```
stack heap
+-----+---+ +---------+
| v | o-|------> | 1 2 3 4 |
+-----+---+ +---------+
| num | ? | ???
+-----+---+
```
---
Example of memory violation in C++
----------------------------------
```c++
#include
#include
using namespace std;
int main() {
vector v = {1, 2, 3};
int *num = &v[2];
v.push_back(4);
cout << *num << endl;
}
```
```sh
$ g++ -std=c++11 vec.cpp
$ ./a.out
-1765327931
$ ./a.out
-1965683886
```
---
Rust type system prevents this
------------------------------
```rust
fn main() {
let mut v = vec![1, 2, 3];
let num = &v[2];
v.push(4);
println!("{}", *num);
}
```
---
Rust type system prevents this
------------------------------
```rust
$ rustc vec.rs
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> vec.rs:4:5
|
3 | let num = &v[2];
| - immutable borrow occurs here
4 | v.push(4);
| ^^^^^^^^^ mutable borrow occurs here
5 | println!("{}", *num);
| ---- immutable borrow later used here
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0502`.
```
---
Intro to Ownership and friends
------------------------------
## Ownership - one and only owner
- transferrable
## Borrowing
- one mutable borrow (read-only)
- many immutable borrow (read-write)
- cannot have both mutable borrow and immutable borrow
## Lifetime
- cleaned automatically once out of scope
Prevents memory-safety issues and *data races*.
---
Permissions model of ownership
------------------------------

---
Resources
---------
- [](https://cel.cs.brown.edu/aquascope/)
- [](https://rust-book.cs.brown.edu/ch04-01-what-is-ownership.html)
---
A Trait Debugger
================
---
Intro to Trait
--------------
```rust
trait ToString {
fn to_string(&self) -> String;
}
impl ToString for i32 {
fn to_string(&self) -> String { todo!() }
}
impl ToString for (S, T)
where
S: ToString,
T: ToString,
{
fn to_string(&self) -> String {
format!(
"({}, {})",
self.0.to_string(),
self.1.to_string())
}
}
```
```rust
fn print_items(items: &[T])
where
T: ToString,
{
for item in items {
println!("{}", item.to_string());
}
}
fn main() {
print_items(&[1, 2]);
}
```
```rust {1|1-3|1-4|all}
(i32, i32): ToString?
(i32, i32): ToString :-
i32: ToString
i32: ToString?
i32: ToString
```
---
Intro to Trait
--------------
```rust {0}
trait ToString {
fn to_string(&self) -> String;
}
impl ToString for i32 {
fn to_string(&self) -> String { todo!() }
}
impl ToString for (S, T)
where
S: ToString,
T: ToString,
{
fn to_string(&self) -> String {
format!(
"({}, {})",
self.0.to_string(),
self.1.to_string())
}
}
```
```rust {12} +line_numbers
fn print_items(items: &[T])
where
T: ToString,
{
for item in items {
println!("{}", item.to_string());
}
}
fn main() {
print_items(&[1, 2]);
print_items(&[true, false]);
}
```
```rust
(bool, bool): ToString?
(bool, bool): ToString :-
bool: ToString
bool: ToString? no
```
---
Show error
----------
*to-string compile error*
---
Diesel: inserting into the wrong table
--------------------------------------

```text
= note: the full name for the type has been written to '[…].txt'
```
---
Resources
---------
- [](https://github.com/cognitive-engineering-labs/argus)
---
A Program Slicer
================
---
Demo
----
---
Slices are built on aliasing and mutation
-----------------------------------------
```python
v = ["Hello"]
s = v[0]
s += " world"
print(v)
````
Does `print` depends on `append`?
*no*
```python
v = ["hello"]
v[0] += " world"
print(v)
```
` += `
mutates ``
`v[0]` refers to (or "aliases")
part of `v`
`s` do not alias `v`
```python
v = ["hello"]
s = mystery1(v)
mystery2(s)
print(v)
```
How do we know what is in the black-box functions?
---
Ownership types enable modular slicing
--------------------------------------
```rust
let mut v = vec![String::from("hello")];
let s = v.get_mut(0).unwrap();
// how do we know get_mut returns a pointer to v?
s.push_str(" world");
// how do we know push_str mutates s?
println!("{v:?}");
```
In C++: `s` has type `*string`
In Rust: `s` has type `&'a mut String`
---
Ownership types enable modular slicing
--------------------------------------
```rust
let mut v = vec![String::from("hello")];
let s = v.get_mut(0).unwrap();
// how do we know get_mut returns a pointer to v?
// get_mut requires that s has the same lifetime as v
s.push_str(" world");
// how do we know push_str mutates s?
println!("{v:?}");
```
In C++: `s` has type `*string`
In Rust: `s` has type `&'a mut String`
---
Ownership types enable modular slicing
--------------------------------------
```rust
let mut v = vec![String::from("hello")];
let s = v.get_mut(0).unwrap();
// how do we know get_mut returns a pointer to v?
// get_mut requires that s has the same lifetime as v
s.push_str(" world");
// how do we know push_str mutates s?
// push_str requires that s is a mutable reference
println!("{v:?}");
```
In C++: `s` has type `*string`
In Rust: `s` has type `&'a mut String`
---
Resources
---------
- [Modular Information Flow through Ownership 2022](https://arxiv.org/abs/2111.13662)
- [](https://github.com/willcrichton/flowistry)