The design philosophy of Rust

What makes Rust successful?

Table Of Contents

  1. An overview of Rust
  2. Rust is ahead-of-time compiled with a strong type system
  3. Rust supports multiple programming paradigms
  4. Rust is memory-safe

The history of Rust

  • In development since 2006, first stable version in 2015
  • Development managed by the Rust Foundation since 2021
  • Started out with garbage collection and object-orientation, now we have borrow checking and no objects
  • “technology from the past come to save the future from itself” [Hoare 2010]

Why another language?

  • Memory safety issues with C/C++
    • Buffer overruns, use-after-free etc.
  • Make concurrent programming easier
    • Prevent race conditions
  • A desire for better tooling
    • Make adding dependencies easier
    • Unify testing, documentation, publishing, benchmarking etc.

How?

  • Many requirements:
    • As fast as C
    • As safe as a GC language
    • As expressive as functional languages
  • Three main components:
    • A strong type system
    • Solving memory safety at the type-level
    • Picking the best of many different programming paradigms

A working C++ program (sometimes)

int main() {
    std::vector<int> v = {1, 2, 3};
    int* p = &v[0];   

    v.push_back(41);   
    *p = 42;          

    std::cout << v[0] << std::endl;
}

A buggy C++ program (sometimes)

int main() {
    std::vector<int> v = {1, 2, 3, 4};
    int* p = &v[0];   

    v.push_back(41);   
    *p = 42;          // SEGFAULT

    std::cout << v[0] << std::endl;
}

What is going on here?

From the documentation of push_back: “[…] all iterators (including the end() iterator) and all references to the elements are invalidated”

Translated to Rust

fn main() {
    let mut v = vec![1, 2, 3, 4];
    let p = &v[0]; 

1    v.push(41);
    println!("{}", p);
}
1
Compile error: cannot borrow v as mutable because it is also borrowed as immutable

Introduction to the Rust type system