SlideShare a Scribd company logo
Why Rust?
Mats Kindahl
<2018-09-08 Sat>
Mats Kindahl Why Rust? <2018-09-08 Sat> 1 / 44
Outline
1 Introduction
2 Some Motivating Examples
3 A Little Rust
4 Functional programming features
5 Closing comments
Mats Kindahl Why Rust? <2018-09-08 Sat> 2 / 44
Introduction
Who am I?
Senior Software Engineer at Timescale
Earlier work involves
Compiler Implementation (C/C++)
Databases (MySQL)
Real-Time Media (Video Conferencing Backend)
Long time C/C++ programmer
. . . and a bunch of other languages
You can nd me on LinkedIn
Mats Kindahl Why Rust? 2018-09-08 Sat 4 / 44
Introduction
What is Rust
Rust is a systems programming language that runs blazingly fast,
prevents segfaults, and guarantees thread safety.
 www.rust-lang.org
Mats Kindahl Why Rust? 2018-09-08 Sat 5 / 44
Introduction
Rust Language Features
Ownership system prevent data races (more about that later)
Powerful type system (inspired by Haskell?)
Parameterized types (Haskell: type parameters, C++: templates)
Traits (Haskell: type classes, Go: interfaces)
Enum (Haskell: algebraic data types)
Powerful macro system (inspired by Scheme?)
FFI for integration with other languages (mainly C)
Mats Kindahl Why Rust? 2018-09-08 Sat 6 / 44
Introduction
History of Rust
2006: Started by Graydon Hoare (Mozilla)
2009: Mozilla got involved
May 2015: First stable release (1.0)
December 2018: Rust 2018 (1.31)
September 2019: Current stable release (1.37)
Mats Kindahl Why Rust? 2018-09-08 Sat 7 / 44
Introduction
Rust Governance
Open Source License (MIT, Apache Version 2)
Release train model with six weeks cycle:
nightly Generated every night
beta Branched from nightly every six weeks
stable Promoting beta after six weeks of testing
Transparant language development
Language changes using RFCs which are openly debated
Roadmap developed from RPCs on a yearly basis
Mats Kindahl Why Rust? 2018-09-08 Sat 8 / 44
Introduction
Rust is ecient
Figures from the Benchmark game
Mats Kindahl Why Rust? 2018-09-08 Sat 9 / 44
Some Motivating Examples
Disclaimer
These examples are simplistic and for presentation purposes
Intended to show what Rust attemt so solve
Real world is never this simple
Assumption is that unsafe is not used.
Mats Kindahl Why Rust? 2018-09-08 Sat 11 / 44
Some Motivating Examples
Implicit numerical conversions
#include cstdio
int main() {
// Oops, used int instead of float
int x = 10.5;
printf(%d, x);
}
Mats Kindahl Why Rust? 2018-09-08 Sat 12 / 44
Some Motivating Examples
Implicit truncation
#include cstdio
#include cmath
int main() {
// Oops, used float instead of double
const float x = acos(-1);
// Will print value is 3.1415927410
printf(value is %fn, x);
}
Mats Kindahl Why Rust? 2018-09-08 Sat 13 / 44
Some Motivating Examples
Dangling pointers in C++
int* some_function() {
int x = 47;
return x; // -- Compiler warning
}
int main() {
auto x = some_function();
*x = 4711; // -- Segmentation fault
}
Mats Kindahl Why Rust? 2018-09-08 Sat 14 / 44
Some Motivating Examples
Dangling pointers in Rust
fn some_function() - 'static i32 {
let x : i32 = 47;
return x; // -- Compiler error
}
fn main() {
let ptr = some_function();
*ptr = 4711;
}
Mats Kindahl Why Rust? 2018-09-08 Sat 15 / 44
Some Motivating Examples
Dangling pointers in Rust
error[E0515]: cannot return reference to local variable `x`
-- /tmp/babel-8gQTAg/rust-P9bKjb:4:10
|
4 | return x; // -- Compiler error
| ^^ returns a reference to data owned by the current function
error[E0594]: cannot assign to `*ptr` which is behind a `` reference
-- /tmp/babel-8gQTAg/rust-P9bKjb:9:3
|
8 | let ptr = some_function();
| --- help: consider changing this to be a mutable reference: `mut i32`
9 | *ptr = 4711;
| ^^^^^^^^^^^ `ptr` is a `` reference, so the data it refers to cannot be written
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0515`.
Mats Kindahl Why Rust? 2018-09-08 Sat 16 / 44
Some Motivating Examples
Dangling pointers in C++
void do_stuff(MyClass *object) {
delete object;
}
int main() {
auto object = new MyClass;
do_stuff(object);
std::cout  *object  std::endl;
}
Previous example give warnings with -Wall and -Wpedantic.
This example will not generate a warning.
Mats Kindahl Why Rust? 2018-09-08 Sat 17 / 44
Some Motivating Examples
Iterator example
#include iostream
#include string
#include vector
int main() {
std::vectorstd::string v;
v.push_back(first);
auto x = v.begin();
v.push_back(second);
std::cout  *x  std::endl;
}
Mats Kindahl Why Rust? 2018-09-08 Sat 18 / 44
Some Motivating Examples
Iterator invalidation in C++
Iterators can be invalidated because of container changes
Example: push_back can (but does not have to) invalidate all iterators.
Accessing an invalid iterator can reference unknown memory
Example: if a std::vector is moved as a result of a resize
This is true in both C++ and Rust
Mats Kindahl Why Rust? 2018-09-08 Sat 19 / 44
Some Motivating Examples
Iterator example in Rust
fn main() {
let mut v = vec![];
v.push(first);
let x = v[0];
v.push(second); // -- Compiler error
println!({}, x);
}
Mats Kindahl Why Rust? 2018-09-08 Sat 20 / 44
Some Motivating Examples
Iterator invalidation
error[E0502]: cannot borrow `v` as mutable because it is
also borrowed as immutable
-- iterator.rs:5:5
|
4 | let x = v[0];
| - immutable borrow occurs here
5 | v.push(world);
| ^ mutable borrow occurs here
6 | println!({}, x);
7 | }
| - immutable borrow ends here
Mats Kindahl Why Rust? 2018-09-08 Sat 21 / 44
A Little Rust
Introductory example
fn dot_product(x: Vecf64, y: Vecf64) - f64 {
let mut result: f64 = 0.0;
for i in 0 .. x.len() {
result += x[i] * y[i];
}
return result;
}
fn main() {
let x = vec![1.0, 2.0, 3.0];
let y = vec![2.0, 4.0, 6.0];
println!(Result: {}, dot_product(x, y));
}
Mats Kindahl Why Rust? 2018-09-08 Sat 23 / 44
A Little Rust
Memory Safety
Rust provide memory safety without garbage collection
No explicit memory allocation
No null pointers (!)
Borrow checker to avoid accessing invalid data
It is not possible to accidentally:
Access uninitialized data
Use dangling pointers
Use deleted memory or delete it twice
Use invalidated iterators
Mats Kindahl Why Rust? 2018-09-08 Sat 24 / 44
A Little Rust
Variables have scope
fn do_stuff(object: MyClass) {
// Do something
}
fn main() {
let object = MyClass::new();
do_stuff(object);
println!({}, object);
// 'object' goes out of scope, will be destroyed
}
No explicit delete.
Variables going out of scope will be destroyed.
Closely related to variable ownership (covered soon)
Mats Kindahl Why Rust? 2018-09-08 Sat 25 / 44
A Little Rust
Optional values
fn find(list: Veci32, value: i32) - Optionusize {
for i in 1..list.len() {
if list[i] == value {
return Some(i);
}
}
return None;
}
fn main() {
let list = vec![6,3,8,7,3];
if let Some(idx) = find(list, 7) {
println!(Found {} at index {}, 7, idx);
}
}
Mats Kindahl Why Rust? 2018-09-08 Sat 26 / 44
A Little Rust
Ownership and borrowing
... and the borrow checker
Ownership and borrowing
Central to the memory safety features of Rust
Allow Rust to not do garbage collection
Ownership and borrowsing prevents data races
More than one concurrent access to an object
One access is a write
The accesses are not synchronized
Ownership and borrow rules checked at compile time
Mats Kindahl Why Rust? 2018-09-08 Sat 27 / 44
A Little Rust
Ownership
struct Dimen {
height: u32,
width: u32,
}
fn main() {
let dim = Dimen { height: 400, width: 600 };
println!(dim: {}x{}, dim.width, dim.height);
} // 'dim' scope ends here: will be destroyed
Every value is owned by a variable.
There is only a single owner at each time.
When the owner goes out of scope, the value is dropped.
Ownership can be transferred to other variables.
Mats Kindahl Why Rust? 2018-09-08 Sat 28 / 44
A Little Rust
Ownership
Move semantics: changing owner of values
fn show_dimen(dim: Dimen) {
println!({}x{}, dim.width, dim.height);
} // 'dim' scope ends here: will be destroyed
fn main() {
let dim = Dimen { height: 400, width: 600 };
show_dimen(dim);
println!(height: {}, dim.height); // -- Compiler error
}
Mats Kindahl Why Rust? 2018-09-08 Sat 29 / 44
A Little Rust
Borrowing
Immutable borrow: temporary read access to value
fn show_dimen(dim: Dimen) {
println!({}x{}, dim.height, dim.width);
}
fn main() {
let data = Dimen { height: 400, width: 600 };
show_dimen(data);
show_dimen(data);
}
Mats Kindahl Why Rust? 2018-09-08 Sat 30 / 44
A Little Rust
Borrowing
Mutable borrow: temporary read/write access to value
fn scale_to(dim: mut Dimen, percent: u32) {
dim.height = dim.height * percent / 100;
dim.width = dim.width * percent / 100;
}
fn main() {
let mut data = Dimen { height: 400, width: 600 };
scale_to(mut data, 50);
show_dimen(data);
}
Mats Kindahl Why Rust? 2018-09-08 Sat 31 / 44
A Little Rust
Borrowing
Rules
1 You have a single mutable borrow of a value or
2 You have one or more immutable borrows of a value.
3 The lifetime of a borrow may not exceed the lifetime of the owner.
When borrowing and moving does not cut it:
Move semantics is default (cheapest)
Borrow semantics where moving is a problem (cheap)
Copy semantics when borrow is a problem (moderate)
Clone semantics when copy is a problem (can be expensive)
Mats Kindahl Why Rust? 2018-09-08 Sat 32 / 44
Functional programming features
Enumerations
enum Error {
Aborted,
NotFound(String),
Internal{code: u32, msg: String},
}
More similar to std::variant than C/C++ enum.
Used where enum and union are used in C/C++.
Mats Kindahl Why Rust? 2018-09-08 Sat 34 / 44
Functional programming features
Enumerations
Pattern matching
fn to_string(err: Error) - String {
match err {
Error::Aborted = format!(aborted),
Error::NotFound(key) = format!('{}' not found, key),
Error::Internal{code, ref msg} if code != 0 =
format!(internal[{}]: {}, code, msg),
_ = panic!(should not come here)
}
}
Enumerations can be pattern matched
Matching is exhaustive: compiler error if enum not covered
Matches can also be conditional
Mats Kindahl Why Rust? 2018-09-08 Sat 35 / 44
Functional programming features
Closures
fn main() {
let incr = 4;
let adder = |val| { val + incr };
for x in 1..10 {
println!(adder({}): {}, x, adder(x));
}
}
Anonymous functions (similar to lambda in C++)
Implicitly captures variables (in contrast to C++)
Default capture is by borrowing
Move capture can be specied
Mats Kindahl Why Rust? 2018-09-08 Sat 36 / 44
Functional programming features
Iterators
fn main() {
let v = vec![10,12,32,1,5];
for e in v {
println!(e: {}, e);
}
}
Iterate over a collection (for example) as a sequence
You can dene iterators for custom data types
Mats Kindahl Why Rust? 2018-09-08 Sat 37 / 44
Functional programming features
Iterators and Closures
fn main() {
let v = vec![1,19,2,5];
let vec_plus_1: Vec_ = v.iter().map(|x| x+1).collect();
println!({:?}, vec_plus_1);
}
Closures are very useful with iterators
Many methods for iterators taking closures
Iterators are lazy: evaluate to get a result
Iterators and closures often faster than for-loops
Mats Kindahl Why Rust? 2018-09-08 Sat 38 / 44
Functional programming features
Chaining iterators
A more complicated example
fn dot_product(x: [f64], y: [f64]) - f64 {
x.iter().zip(y).map(|(a, b)| a * b).sum()
}
fn main() {
let x = [1.0, 2.0, 3.0];
let y = [2.0, 4.0, 6.0];
println!(Result: {}, dot_product(x, y));
}
Mats Kindahl Why Rust? 2018-09-08 Sat 39 / 44
Closing comments
Cargo
The Rust project manager
Manages dependencies
Documentation
Similar to JavaDoc
Testing
Unit tests
Integration tests
Documentation tests
Benchmarking
Creates and uploads packages
Integrates with crates.io
Mats Kindahl Why Rust? 2018-09-08 Sat 41 / 44
Closing comments
Cargo
~$ cargo new oyster --bin
Created binary (application) `oyster` project
~$ cd oyster/
~/oyster$ cargo build
Compiling oyster v0.1.0 (file:///home/matski/oyster)
Finished dev [unoptimized + debuginfo] target(s) in 0.47s
~/oyster$ cargo test
Compiling oyster v0.1.0 (file:///home/matski/oyster)
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
Running target/debug/deps/oyster-5a63e052e9010699
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Mats Kindahl Why Rust? 2018-09-08 Sat 42 / 44
Closing comments
Crates.io
The Rust package registry
Community-driven
Contains approx. 19,000
crates
Integrates with Cargo
serde serialization and deserialization
of objects
disel object-relational (ORM)
mapping for databases
log logging
rand random number generation
tokio asynchronous, event-driven
platform
Mats Kindahl Why Rust? 2018-09-08 Sat 43 / 44
Closing comments
Questions
Any questions?
Mats Kindahl Why Rust? 2018-09-08 Sat 44 / 44

More Related Content

Why rust?

  • 1. Why Rust? Mats Kindahl <2018-09-08 Sat> Mats Kindahl Why Rust? <2018-09-08 Sat> 1 / 44
  • 2. Outline 1 Introduction 2 Some Motivating Examples 3 A Little Rust 4 Functional programming features 5 Closing comments Mats Kindahl Why Rust? <2018-09-08 Sat> 2 / 44
  • 3. Introduction Who am I? Senior Software Engineer at Timescale Earlier work involves Compiler Implementation (C/C++) Databases (MySQL) Real-Time Media (Video Conferencing Backend) Long time C/C++ programmer . . . and a bunch of other languages You can nd me on LinkedIn Mats Kindahl Why Rust? 2018-09-08 Sat 4 / 44
  • 4. Introduction What is Rust Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. www.rust-lang.org Mats Kindahl Why Rust? 2018-09-08 Sat 5 / 44
  • 5. Introduction Rust Language Features Ownership system prevent data races (more about that later) Powerful type system (inspired by Haskell?) Parameterized types (Haskell: type parameters, C++: templates) Traits (Haskell: type classes, Go: interfaces) Enum (Haskell: algebraic data types) Powerful macro system (inspired by Scheme?) FFI for integration with other languages (mainly C) Mats Kindahl Why Rust? 2018-09-08 Sat 6 / 44
  • 6. Introduction History of Rust 2006: Started by Graydon Hoare (Mozilla) 2009: Mozilla got involved May 2015: First stable release (1.0) December 2018: Rust 2018 (1.31) September 2019: Current stable release (1.37) Mats Kindahl Why Rust? 2018-09-08 Sat 7 / 44
  • 7. Introduction Rust Governance Open Source License (MIT, Apache Version 2) Release train model with six weeks cycle: nightly Generated every night beta Branched from nightly every six weeks stable Promoting beta after six weeks of testing Transparant language development Language changes using RFCs which are openly debated Roadmap developed from RPCs on a yearly basis Mats Kindahl Why Rust? 2018-09-08 Sat 8 / 44
  • 8. Introduction Rust is ecient Figures from the Benchmark game Mats Kindahl Why Rust? 2018-09-08 Sat 9 / 44
  • 9. Some Motivating Examples Disclaimer These examples are simplistic and for presentation purposes Intended to show what Rust attemt so solve Real world is never this simple Assumption is that unsafe is not used. Mats Kindahl Why Rust? 2018-09-08 Sat 11 / 44
  • 10. Some Motivating Examples Implicit numerical conversions #include cstdio int main() { // Oops, used int instead of float int x = 10.5; printf(%d, x); } Mats Kindahl Why Rust? 2018-09-08 Sat 12 / 44
  • 11. Some Motivating Examples Implicit truncation #include cstdio #include cmath int main() { // Oops, used float instead of double const float x = acos(-1); // Will print value is 3.1415927410 printf(value is %fn, x); } Mats Kindahl Why Rust? 2018-09-08 Sat 13 / 44
  • 12. Some Motivating Examples Dangling pointers in C++ int* some_function() { int x = 47; return x; // -- Compiler warning } int main() { auto x = some_function(); *x = 4711; // -- Segmentation fault } Mats Kindahl Why Rust? 2018-09-08 Sat 14 / 44
  • 13. Some Motivating Examples Dangling pointers in Rust fn some_function() - 'static i32 { let x : i32 = 47; return x; // -- Compiler error } fn main() { let ptr = some_function(); *ptr = 4711; } Mats Kindahl Why Rust? 2018-09-08 Sat 15 / 44
  • 14. Some Motivating Examples Dangling pointers in Rust error[E0515]: cannot return reference to local variable `x` -- /tmp/babel-8gQTAg/rust-P9bKjb:4:10 | 4 | return x; // -- Compiler error | ^^ returns a reference to data owned by the current function error[E0594]: cannot assign to `*ptr` which is behind a `` reference -- /tmp/babel-8gQTAg/rust-P9bKjb:9:3 | 8 | let ptr = some_function(); | --- help: consider changing this to be a mutable reference: `mut i32` 9 | *ptr = 4711; | ^^^^^^^^^^^ `ptr` is a `` reference, so the data it refers to cannot be written error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0515`. Mats Kindahl Why Rust? 2018-09-08 Sat 16 / 44
  • 15. Some Motivating Examples Dangling pointers in C++ void do_stuff(MyClass *object) { delete object; } int main() { auto object = new MyClass; do_stuff(object); std::cout *object std::endl; } Previous example give warnings with -Wall and -Wpedantic. This example will not generate a warning. Mats Kindahl Why Rust? 2018-09-08 Sat 17 / 44
  • 16. Some Motivating Examples Iterator example #include iostream #include string #include vector int main() { std::vectorstd::string v; v.push_back(first); auto x = v.begin(); v.push_back(second); std::cout *x std::endl; } Mats Kindahl Why Rust? 2018-09-08 Sat 18 / 44
  • 17. Some Motivating Examples Iterator invalidation in C++ Iterators can be invalidated because of container changes Example: push_back can (but does not have to) invalidate all iterators. Accessing an invalid iterator can reference unknown memory Example: if a std::vector is moved as a result of a resize This is true in both C++ and Rust Mats Kindahl Why Rust? 2018-09-08 Sat 19 / 44
  • 18. Some Motivating Examples Iterator example in Rust fn main() { let mut v = vec![]; v.push(first); let x = v[0]; v.push(second); // -- Compiler error println!({}, x); } Mats Kindahl Why Rust? 2018-09-08 Sat 20 / 44
  • 19. Some Motivating Examples Iterator invalidation error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable -- iterator.rs:5:5 | 4 | let x = v[0]; | - immutable borrow occurs here 5 | v.push(world); | ^ mutable borrow occurs here 6 | println!({}, x); 7 | } | - immutable borrow ends here Mats Kindahl Why Rust? 2018-09-08 Sat 21 / 44
  • 20. A Little Rust Introductory example fn dot_product(x: Vecf64, y: Vecf64) - f64 { let mut result: f64 = 0.0; for i in 0 .. x.len() { result += x[i] * y[i]; } return result; } fn main() { let x = vec![1.0, 2.0, 3.0]; let y = vec![2.0, 4.0, 6.0]; println!(Result: {}, dot_product(x, y)); } Mats Kindahl Why Rust? 2018-09-08 Sat 23 / 44
  • 21. A Little Rust Memory Safety Rust provide memory safety without garbage collection No explicit memory allocation No null pointers (!) Borrow checker to avoid accessing invalid data It is not possible to accidentally: Access uninitialized data Use dangling pointers Use deleted memory or delete it twice Use invalidated iterators Mats Kindahl Why Rust? 2018-09-08 Sat 24 / 44
  • 22. A Little Rust Variables have scope fn do_stuff(object: MyClass) { // Do something } fn main() { let object = MyClass::new(); do_stuff(object); println!({}, object); // 'object' goes out of scope, will be destroyed } No explicit delete. Variables going out of scope will be destroyed. Closely related to variable ownership (covered soon) Mats Kindahl Why Rust? 2018-09-08 Sat 25 / 44
  • 23. A Little Rust Optional values fn find(list: Veci32, value: i32) - Optionusize { for i in 1..list.len() { if list[i] == value { return Some(i); } } return None; } fn main() { let list = vec![6,3,8,7,3]; if let Some(idx) = find(list, 7) { println!(Found {} at index {}, 7, idx); } } Mats Kindahl Why Rust? 2018-09-08 Sat 26 / 44
  • 24. A Little Rust Ownership and borrowing ... and the borrow checker Ownership and borrowing Central to the memory safety features of Rust Allow Rust to not do garbage collection Ownership and borrowsing prevents data races More than one concurrent access to an object One access is a write The accesses are not synchronized Ownership and borrow rules checked at compile time Mats Kindahl Why Rust? 2018-09-08 Sat 27 / 44
  • 25. A Little Rust Ownership struct Dimen { height: u32, width: u32, } fn main() { let dim = Dimen { height: 400, width: 600 }; println!(dim: {}x{}, dim.width, dim.height); } // 'dim' scope ends here: will be destroyed Every value is owned by a variable. There is only a single owner at each time. When the owner goes out of scope, the value is dropped. Ownership can be transferred to other variables. Mats Kindahl Why Rust? 2018-09-08 Sat 28 / 44
  • 26. A Little Rust Ownership Move semantics: changing owner of values fn show_dimen(dim: Dimen) { println!({}x{}, dim.width, dim.height); } // 'dim' scope ends here: will be destroyed fn main() { let dim = Dimen { height: 400, width: 600 }; show_dimen(dim); println!(height: {}, dim.height); // -- Compiler error } Mats Kindahl Why Rust? 2018-09-08 Sat 29 / 44
  • 27. A Little Rust Borrowing Immutable borrow: temporary read access to value fn show_dimen(dim: Dimen) { println!({}x{}, dim.height, dim.width); } fn main() { let data = Dimen { height: 400, width: 600 }; show_dimen(data); show_dimen(data); } Mats Kindahl Why Rust? 2018-09-08 Sat 30 / 44
  • 28. A Little Rust Borrowing Mutable borrow: temporary read/write access to value fn scale_to(dim: mut Dimen, percent: u32) { dim.height = dim.height * percent / 100; dim.width = dim.width * percent / 100; } fn main() { let mut data = Dimen { height: 400, width: 600 }; scale_to(mut data, 50); show_dimen(data); } Mats Kindahl Why Rust? 2018-09-08 Sat 31 / 44
  • 29. A Little Rust Borrowing Rules 1 You have a single mutable borrow of a value or 2 You have one or more immutable borrows of a value. 3 The lifetime of a borrow may not exceed the lifetime of the owner. When borrowing and moving does not cut it: Move semantics is default (cheapest) Borrow semantics where moving is a problem (cheap) Copy semantics when borrow is a problem (moderate) Clone semantics when copy is a problem (can be expensive) Mats Kindahl Why Rust? 2018-09-08 Sat 32 / 44
  • 30. Functional programming features Enumerations enum Error { Aborted, NotFound(String), Internal{code: u32, msg: String}, } More similar to std::variant than C/C++ enum. Used where enum and union are used in C/C++. Mats Kindahl Why Rust? 2018-09-08 Sat 34 / 44
  • 31. Functional programming features Enumerations Pattern matching fn to_string(err: Error) - String { match err { Error::Aborted = format!(aborted), Error::NotFound(key) = format!('{}' not found, key), Error::Internal{code, ref msg} if code != 0 = format!(internal[{}]: {}, code, msg), _ = panic!(should not come here) } } Enumerations can be pattern matched Matching is exhaustive: compiler error if enum not covered Matches can also be conditional Mats Kindahl Why Rust? 2018-09-08 Sat 35 / 44
  • 32. Functional programming features Closures fn main() { let incr = 4; let adder = |val| { val + incr }; for x in 1..10 { println!(adder({}): {}, x, adder(x)); } } Anonymous functions (similar to lambda in C++) Implicitly captures variables (in contrast to C++) Default capture is by borrowing Move capture can be specied Mats Kindahl Why Rust? 2018-09-08 Sat 36 / 44
  • 33. Functional programming features Iterators fn main() { let v = vec![10,12,32,1,5]; for e in v { println!(e: {}, e); } } Iterate over a collection (for example) as a sequence You can dene iterators for custom data types Mats Kindahl Why Rust? 2018-09-08 Sat 37 / 44
  • 34. Functional programming features Iterators and Closures fn main() { let v = vec![1,19,2,5]; let vec_plus_1: Vec_ = v.iter().map(|x| x+1).collect(); println!({:?}, vec_plus_1); } Closures are very useful with iterators Many methods for iterators taking closures Iterators are lazy: evaluate to get a result Iterators and closures often faster than for-loops Mats Kindahl Why Rust? 2018-09-08 Sat 38 / 44
  • 35. Functional programming features Chaining iterators A more complicated example fn dot_product(x: [f64], y: [f64]) - f64 { x.iter().zip(y).map(|(a, b)| a * b).sum() } fn main() { let x = [1.0, 2.0, 3.0]; let y = [2.0, 4.0, 6.0]; println!(Result: {}, dot_product(x, y)); } Mats Kindahl Why Rust? 2018-09-08 Sat 39 / 44
  • 36. Closing comments Cargo The Rust project manager Manages dependencies Documentation Similar to JavaDoc Testing Unit tests Integration tests Documentation tests Benchmarking Creates and uploads packages Integrates with crates.io Mats Kindahl Why Rust? 2018-09-08 Sat 41 / 44
  • 37. Closing comments Cargo ~$ cargo new oyster --bin Created binary (application) `oyster` project ~$ cd oyster/ ~/oyster$ cargo build Compiling oyster v0.1.0 (file:///home/matski/oyster) Finished dev [unoptimized + debuginfo] target(s) in 0.47s ~/oyster$ cargo test Compiling oyster v0.1.0 (file:///home/matski/oyster) Finished dev [unoptimized + debuginfo] target(s) in 0.50s Running target/debug/deps/oyster-5a63e052e9010699 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Mats Kindahl Why Rust? 2018-09-08 Sat 42 / 44
  • 38. Closing comments Crates.io The Rust package registry Community-driven Contains approx. 19,000 crates Integrates with Cargo serde serialization and deserialization of objects disel object-relational (ORM) mapping for databases log logging rand random number generation tokio asynchronous, event-driven platform Mats Kindahl Why Rust? 2018-09-08 Sat 43 / 44
  • 39. Closing comments Questions Any questions? Mats Kindahl Why Rust? 2018-09-08 Sat 44 / 44