Me
NN ➡️ Helsinki ➡️ Singapore ➡️ Tokyo
C, Python, Scala
Interests: Functional Programming, Computer Graphics (GLSL), Programming Languages & PL design
History
2010 Pet project by Graydon Hoare at Mozilla Research
2015 Hits 1.0
2016 Firefox Quantum
2018 Rust 👀 Me
Bullet points
- Strong static typing 1
- Type inference
- No GC
- No exceptions
- No
null
's * - Memory safety *
fn main() { let a = vec![1, 2, 3, 4, 5]; println!("{:?}", a); let sum: u32 = a.iter().sum(); println!("{}", sum); }
Ownership & Borrowing
T
- owned value of typeT
&T
- reference to value of typeT
fn sum(a: &Vec<u32>) -> u32 { a.iter().sum() } fn add_one(a: Vec<u32>) -> Vec<u32> { a.into_iter().map(|e| e + 1).collect() } fn main() { let a = vec![1, 2, 3, 4, 5]; println!("{}", sum(&a)); println!("{:?}", add_one(a)); }
Mutation | Aliasing
&mut T
- unique reference to value of typeT
- many
&T
or one&mut T
at the same time
fn add_one_inplace(a: &mut Vec<u32>) { for e in a.iter_mut() { *e += 1; } } fn main() { let mut a = vec![1, 2, 3, 4, 5]; println!("{:?}", a); for _ in 0..3 { add_one_inplace(&mut a); } println!("{:?}", a); }
Example: Mutex
In imaginary game engine
class Posion:
def onTick(self):
self.entity.health -= 1
class Missile:
def onCollide(self, entity):
with entity.lock():
entity.health -= 10
In Rust Mutex
owns its underlying data
use std::sync::Mutex; fn main() { let entity: u32 = 0; let e = Mutex::new(entity); e.lock(); }
Source: RustConf 2021 Compile-Time Social Coordination 1
Structs & Impls
struct Point { x: f32, y: f32, } impl Point { fn distance(&self, other: &Point) -> f32 { ((self.x - other.x).powf(2.) + (self.y - other.y).powf(2.)).sqrt() } fn shift(&mut self, x: f32, y: f32) { self.x += x; self.y += y; } } fn main() { let origin = Point { x: 0., y: 0. }; let mut p1 = Point { x: 0., y: 2. }; println!("distance {}", origin.distance(&p1)); p1.shift(5., -2.); println!("distance {}", origin.distance(&p1)); }
Algebraic Data Types & Pattern Matching
enum Option<T> { None, Some(T), } fn test(values: Option<&Vec<u32>>) -> String { match values { Option::None => "none".to_string(), Option::Some(v) if v.len() > 3 => "3+".to_string(), Option::Some(v) => v.len().to_string(), } } fn main() { let v = vec![1, 2, 3, 4]; println!("{}", test(Option::Some(&v))); }
Manual Memory
Types need to have known size
enum List<T> { Nil, Cons(T, Box<List<T>>), } fn main() {}
Box
is a heap pointer 1Box
pointer is nevernull
Box
pointer gets deallocated when the handle goes out of scope
Other kinds of managed pointers 1
Manual Memory
It gets worse
use std::rc::Rc; use std::cell::RefCell; type Link<T> = Rc<RefCell<Node<T>>>; struct Node<T> { data: T, next: Option<Link<T>>, previous: Option<Link<T>>, } fn main() {}
Rc
is reference counting pointer 1- copying
Rc
increments counter - when
Rc
handle goes out of scope it decrements counter RefCell
is a type that allows interior mutability 1
Too Many Linked Lists 1
Traits
- No inheritance
- Behavior described through traits
struct Point { x: f32, y: f32, } trait Show { fn show(&self) -> String; } impl Show for Point { fn show(&self) -> String { format!("{};{}", self.x, self.y) } } fn main() { let p = Point { x: 0.5, y: 1.3 }; println!("{}", p.show()); }
Parameter polymorphism
Add guards to generic arguments to describe fine-grained behavior
trait Show { fn show(&self) -> String; } enum List<T> { Nil, Cons(T, Box<List<T>>), } impl<T: Show> Show for List<T> { fn show(&self) -> String { match self { List::Nil => "Nil".to_string(), List::Cons(t, l) => format!("{} -> {}", t.show(), l.show()) } } } impl Show for u32 { fn show(&self) -> String { self.to_string() } } fn main() { let l = List::Cons(10, Box::new(List::Cons(5, Box::new(List::Nil)))); println!("{}", l.show()); }
For dynamic dispatch see also chapter on trait objects 1
stm32
Blue Pill: stm32f103c8t6
- ARM Cortex-M3
- 32 bit, 1-core
- 72 Mhz clock
- 64 KB FLASH
- 20 KB RAM
Demos: stm32
Libraries & Tools
WebAssembly
- Binary executable format
- Supported by all major browsers
- Linear memory
Rust
Demos: WASM
Simplex Noise Procedural Generation
Notable features
Most references from The Rust Book
- Ownership & Borrowing
- Algebraic Data Types
- Parametric polymorphism
- Pattern matching
- Hygenic macros
- Async programming*
How to get started
Check out the book on WebAssebmly
Some community resources
Projects
- Desktop (Servo, Tauri Apps)
- Embedded (HAL, stm32),
no_std
1 - Services, backend (Tokio)
- Graphics/Games (Bevy, godot-rust, Embark Open-Source projects)
- Frontend (WebAssembly) (EGUI, Seed, Yew)
- Blockchain (Solana)
Stories
- Discord cache service 1
- ScyllaDB driver (implementation of Cassandra) 1
- Google Security: Android Kernel 1
- Dropbox Capture 1
- Linux Kernel patches to make Rust availiable for contribution 1