Ben Striegel

@bstrie

# SYSTEMS PROGRAMMING FOR THE MODERN DEVELOPER

``````// C
int sum = 0;
for (int i=0; i<x; i++) {
sum += i;
}``````
``````# Python
sum = 0
for i in range(0, x):
sum += i
# `sum()` ist verboten``````
``````// Rust
let mut sum = 0;
for i in 0..x {
sum += i;
}``````
``````
# Ruby
(0...x).inject(0) {|sum, i| sum + i}``````
``````
# Python
reduce(lambda sum, i: sum + i,
range(0, x), 0)``````
``````
// Rust
(0..x).fold(0, |sum, i| sum + i)``````
``````; Assembly
lea	eax, [rdi - 1]
lea	ecx, [rdi - 2]
imul	rcx, rax
shr	rcx
lea	eax, [rcx + rdi - 1]``````
((x - 1) * (x - 2) >> 1) + x - 1
``````// Rust
(0..x).fold(0, |sum, i| sum + i)``````
``````// C, runtime memory error
int* foo() {
int x = 4;
return &x;
}``````
``````// Go, safe thanks to GC
func foo() *int {
x := 4
return &x
}``````
``````// Rust, does not compile
fn foo() -> &i32 {
let x = 4;
return &x;
}``````
``````// Go, with data race
x := 0
for i := 0; i < 10; i++ {
go func() { x += 1 }()
}``````
``````// Go, without data race
mutex := &sync.Mutex{}
x := 0
for i := 0; i < 10; i++ {
go func() {
mutex.Lock()
x += 1
mutex.Unlock()
}()
}``````
``````// Rust, does not compile
let mut x = 0;
for i in 0..10 {
spawn(|| x += 1);
}``````
```error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
--> race.rs:3:11
|
3 |     spawn(|| x += 1);
|           ^^ - `x` is borrowed here
|           |
|           may outlive borrowed value `x`
```
``````// Rust
let x = Arc::new(Mutex::new(0));
for i in 0..10 {
let handle = x.clone();
spawn(move || {
*handle.lock().unwrap() += 1;
});
}``````
``````// C
void foo() {
int bar = 42;
}``````
``````// C
void foo() {
char *ptr = (char*) malloc(42);
free(ptr); // don't forget this!
}``````
``````// C
void foo() {
char *ptr1 = (char*) malloc(42);
char *ptr2 = ptr1;
free(ptr1);
free(ptr2); // what happens now?
}``````
``````// C
void foo() {
char *ptr1 = (char*) malloc(42);
char *ptr2 = ptr1;
free(ptr1);
char *ptr3 = (char*) malloc(42);
free(ptr2); // what happens now?
}``````
``````// Rust
fn foo() {
let ptr1 = String::new();
let ptr2 = ptr1;
}``````
``````// Rust
fn foo() {
let ptr1 = String::new();
let ptr2 = ptr1;
let ptr3 = ptr1; // doesn't compile!
}``````
```error[E0382]: use of moved value: `ptr1`
--> src/lib.rs:5:16
|
3 |     let ptr1 = String::new();
|         ---- move occurs because `ptr1` has type `String`,
|              which does not implement the `Copy` trait
4 |     let ptr2 = ptr1;
|                ---- value moved here
5 |     let ptr3 = ptr1;
|                ^^^^ value used here after move
```
``````// C
void foo() {
int bar = 42;
int qux = bar;
int ham = bar;
}``````
``````// Rust
fn foo() {
let foo = 42;
let qux = foo;
let ham = foo;
}``````
``````// Rust
fn foo() {
let ptr1 = String::new();
let ptr2 = ptr1;
let ptr3 = ptr1; // doesn't compile!
}``````
```error[E0382]: use of moved value: `ptr1`
--> src/lib.rs:5:16
|
3 |     let ptr1 = String::new();
|         ---- move occurs because `ptr1` has type `String`,
|              which does not implement the `Copy` trait
4 |     let ptr2 = ptr1;
|                ---- value moved here
5 |     let ptr3 = ptr1;
|                ^^^^ value used here after move
```
``````// C
void foo() {
char *ptr1 = (char*) malloc(42);
char *ptr2 = ptr1;
free(ptr1);
}``````
``````// Javascript
function foo() {
let bar = [1, 2, 3];
let qux = bar;
}``````
``````// C
void foo() {
char *ptr1 = (char*) malloc(42);
char *ptr2 = ptr1;
// maybe use ptr2 somewhere in here
free(ptr1);
}``````
``````// Rust
fn foo() {
let own = String::new();
let borrow = &own; // note the &
}``````
``````// Rust
fn foo() {
let own = String::new();
let borrow1 = &own;
let borrow2 = &own;
}``````
``````// Rust
fn foo() {
let own = String::new();
let borrow = &own;
borrow.push('x'); // doesn't compile!
}``````
```error[E0596]: cannot borrow `*borrow` as mutable, as it is behind a `&` reference
--> src/lib.rs:5:5
|
5 |     borrow.push('x');
|     ^^^^^^^^^^^^^^^^ `borrow` is a `&` reference,
|                      so the data it refers to
|                      cannot be borrowed as mutable
```
``````// Rust
fn foo() {
let mut own = String::new();
let borrow = &mut own;
borrow.push('a');
}``````
``````// Rust, doesn't compile
fn foo() {
let mut own = String::new();
let borrow1 = &mut own;
let borrow2 = &mut own;
borrow1.push('a');
}``````
```error[E0499]: cannot borrow `own` as mutable more than once at a time
--> src/lib.rs:5:19
|
4 |    let borrow1 = &mut own;
|                  -------- first mutable borrow here
5 |    let borrow2 = &mut own;
|                  ^^^^^^^^ second mutable borrow here
6 |    borrow1.push('a');
|    ----------------- first borrow later used here```
``````// Rust, doesn't compile
fn foo() {
let mut vec = Vec::from([1, 2, 3, 4]);
let borrow = &mut vec;
for num in &vec {
borrow.push(num);
}
}``````
```error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
--> src/lib.rs:5:20
|
4 |     let borrow = &mut vec;
|                  -------- mutable borrow here
5 |     for num in &vec {
|                ^^^^ immutable borrow here
6 |     borrow.push(num);
|     ---------------- mutable borrow later used here```
``````fn main() {
let greeting = "hello";
println!("{}, world", greeting);
}``````
``````struct Point {
x: i32,
y: i32
}

let point = Point { x: 12, y: 34 };

assert!(point.x + point.y == 46);``````
``````enum TrafficLight {
Red,
Yellow,
Green
}

let current_light = Green;

match current_light {
Red => println!("Stop!"),
Yellow => println!("Slow down!"),
Green => println!("Go!")
}``````
``````let foo = "Hello, world!".find(',');
assert!(foo == Some(5));

let bar = "Hello, world!".find('😎');
assert!(bar == None);``````
``````let foo: Result<i32, _> = "42".parse();
assert!(foo == Ok(42));

let bar: Result<i32, _> = "😎".parse();
assert!(bar.is_err());``````
``````let foo: i32 = "42".parse()?;

// Equivalent to:
let foo: i32 = match "42".parse() {
Ok(num) => num,
Err(e) => return Err(e)
};``````
``````// this works:
let foo;

if some_array.is_empty() {
foo = "that array is empty!";
} else {
foo = "no, it ain't!";
}

// or equivalently:
let foo = if some_array.is_empty() {
"that array is empty!"
} else {
"no, it ain't!"
};``````
``````struct Point { x: i32, y: i32 }

impl Point {
fn new(x: i32, y: i32) -> Self {
Point { x, y }
}

self.x + self.y
}
}

let point = Point::new(12, 34);
``````trait PointTrait {
fn new(x: i32, y: i32) -> Self;

}

impl PointTrait for Point {
fn new(x: i32, y: i32) -> Self {
Point { x, y }
}