MRH.io logo

MRH.io logo

Adaptive Leadership for Technical Projects

🌌 OrbitDB
P2P databases for the distributed web, build on CRDTs
πŸ¦€ Rust IPFS
A Rust implementation of the Interplanetary File System
πŸ“ˆ TallyLab
A privacy-first, end-to-end encrypted time-series data platform
βš“ Hack for the Sea
An annual hackathon where technology and the ocean meet.
This website does not track you.
The best way to reach out is via e-mail.

Notes: Making Rust Delightful

RustCon Asia 2019

April 07, 2020 | Rust, Ergnomics

by Nick Cameron
Twitter GitHub

Rust wants to be a β€œpractical” language

Ergonomics: The Absence of friction

Language matches mental model (Variants vs Classes)

People + context are not easy

With crates.io and docs.rs one can study the entire ecosystem

Empathy: imagine who people are, what they are trying to solve

The right thing should be the easiest thing to do

Important should be explicit. Non-important, implicit. Avoid boilerplate

Ownership and borrowing are explicit because they are important

Tools: Put the user first

Consistency. Convention over configuration (the rustup toolchain)

Tools can teach the user (compiler error messages)

Libraries: Minimize duplication

Client simplicity over library simplicity

fn foo(h: HashMap<String, u8>) {
  h.get(&String::new());
  h.get("foo");
  h.insert("bar".to_owned(), 42);
}

get requires a reference

impl<K: Hash, V> HashMap<K, V> {
  fn get<Q: Hash>(&self, k: &Q) -> Option<&V> where K: Borrow<Q>;
}

Implementation always borrows from the Q type

fn foo(h: Hashmap<Vec<u8>, u8>) {
  h.get(vec!());
  h.get(&[1, 2]);
  h.insert(vec![1, 3], 42);
}

Seems odd, but generalizes across all reference types

Language: All about tradeoffs

General vs specific (error handling)

Simple analysis vs easy to use (lexical lifetimes)

Explicit vs implicit (moves implicit, ownership explicit)

Stability without stagnation: Can we do something about Result? What about explicitly borrowing Copy types?

Errors are still not perfect on the tool side