#+STARTUP: beamer #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:nil arch:headline #+OPTIONS: author:t broken-links:nil c:nil creator:nil #+OPTIONS: d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t num:t #+OPTIONS: p:nil pri:nil prop:nil stat:t tags:t tasks:t tex:t #+OPTIONS: timestamp:t title:t toc:t todo:t |:t #+TITLE: \includesvg[height=.25\textheight]{img/rust-logo-blk}\newline An introduction to Rust #+AUTHOR: \href{mailto:finga@onders.org}{finga} #+EMAIL: finga@onders.org #+SUBTITLE: A language empowering everyone to build reliable and efficient software. #+DATE: \today #+DESCRIPTION: An introduction into Rust and its ecosystems. #+LANGUAGE: en #+KEYWORDS: rust programming #+SELECT_TAGS: export #+EXCLUDE_TAGS: noexport #+CREATOR: Emacs 26.1 (Org mode 9.1.9) #+OPTIONS: H:2 #+LATEX_CLASS: beamer #+LATEX_CLASS_OPTIONS: [aspectratio=1610] #+COLUMNS: %45ITEM %10BEAMER_env(Env) %10BEAMER_act(Act) %4BEAMER_col(Col) %8BEAMER_opt(Opt) #+LATEX_HEADER: \usepackage{svg}\hypersetup{colorlinks=true,linkcolor=black,urlcolor=gray} #+BEAMER_THEME: Frankfurt #+BEAMER_COLOR_THEME: seagull #+BEAMER_FONT_THEME: #+BEAMER_INNER_THEME: #+BEAMER_OUTER_THEME: * Rust ** Abstract #+BEGIN_CENTER #+LaTeX:\includegraphics[width = 0.5\textwidth]{img/Bruine_roest_op_tarwe_(Puccinia_recondita_f.sp._tritici_on_Triticum_aestivum).jpg} [fn:rust_fungus] #+END_CENTER *** Rust, the language - First public appearance 2010 - Rust is the coating closest to the bare metal - Memory safe without gcing, optional reference counting - Ownership, lifetimes, traits, functional paradigms, zero-cost and zero-size abstractions - A well designed language and ecosystem ** Strengths and Weaknesses[fn:strengths] *** Things Rust does measurably really well (Strengths) - Compiled code [[https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fastest.html][about same performance as C / C++]], and excellent [[https://dl.acm.org/doi/10.1145/3136014.3136031][memory and energy efficiency]]. - Can [[https://www.chromium.org/Home/chromium-security/memory-safety][avoid 70% of all safety issues]] present in C / C++, and most memory issues. - Strong type system prevents [[https://doc.rust-lang.org/nomicon/races.html][data races]], brings [[https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html]['fearless concurrency']] (amongst others). - Seamless C interop, and [[https://doc.rust-lang.org/rustc/platform-support.html][dozens of supported platforms]] (based on LLVM).[fn:lwn_gcc][fn:gcc] - [[https://insights.stackoverflow.com/survey/2021#technology-most-loved-dreaded-and-wanted]["Most loved language"]] for 6 years in a row. - Modern tooling: ~cargo~ (builds just work), ~clippy~ (450+ code quality lints), ~rustup~ (easy toolchain management). ** Strengths and Weaknesses[fn:weaknesses] *** Points you might run into (Weaknesses) - Steep learning curve[fn:survey] compiler enforcing (esp. memory) rules that would be "best practices" elsewhere. - Missing Rust-native libs in some domains, target platforms (esp. embedded), IDE features.[fn:survey] - Longer compile times than "similar" code in other languages.[fn:survey][fn:compiler_speed] - No formal language specification, can prevent legal use in some domains (aviation, medical, ...).[fn:specification] - Careless (use of ~unsafe~ in) libraries can secretly break safety guarantees. ** Problems Rust tries to conquer #+BEGIN_CENTER #+LaTeX:\includegraphics[width = 0.8\textwidth]{img/compiler_complaint.png} [fn:xkcd_dangling_pointer] #+END_CENTER - Dangling pointers / memory safety - Iterator invalidation - Thread safety / concurreny - Segfaults - Error handling - Zero-cost and zero-size abstractions ** Where to start? *** First Steps - [[https://tourofrust.com/TOC_en.html][Tour of Rust]] - [[https://doc.rust-lang.org/book/][The Rust Book]] (~$ rustup docs --book~) - [[https://dhghomon.github.io/easy_rust/Chapter_1.html][Rust in Easy English]] - [[https://doc.rust-lang.org/rust-by-example/][Rust by Example]] (~$ rustup docs --rust-by-example~) - [[https://doc.rust-lang.org/std/][The Rust Standard Library]] (~$ rustup docs --std~) - [[https://doc.rust-lang.org/nomicon/][The Rustonomicon]]: The Art of unsafe Rust (~$ rustup docs --nomicon~) - Use '~$ rustup help docs~' to get an overview *** Compact "cheat sheets" - [[https://cheats.rs][cheats.rs]] - [[https://programming-idioms.org/cheatsheet/Rust][programming-idioms.org]] ** Where to continue? *** Further Steps - [[https://www.youtube.com/channel/UC_iD0xppBwwsrM9DegC5cQQ][Jon Gjengset]] (Considering Rust, Crust of Rust, Advanced topics in Rust) ** Where to share, find help and stay up to date *** Online sharing/testing - [[https://play.rust-lang.org/][play.rust-lang.org]] - [[https://godbolt.org/][godbolt.org]] (Supports not only Rust) *** Chat (Discord) - [[https://discord.gg/rust-lang][The Rust Programming Language]] - [[https://discord.com/invite/tcbkpyQ][The Rust Programming Language Community Server]] *** Boards and Blogs - [[https://blog.rust-lang.org/][Rust Blog]] - [[https://www.reddit.com/r/rust][r/rust]] - [[https://this-week-in-rust.org/][This Week in Rust]] ** Language - Semicolons have meaning (statements vs. expressions) - Mutability - Shadowing - Memory safety - Ownership, references and lifetimes - Functional paradigms - Pattern matching - Metaprogramming (declarative and procedural macros) - Meaningful compiler warnings and errors ** Statements vs. expressions *** Statements #+BEGIN_SRC rust let something = true; fn_call(); #+END_SRC *** Expressions ~()~, ~false~, ~x + y~, ~fn_call()~, ~if~, ~match~ *** Example #+BEGIN_SRC rust let bool_value = true; let value = if bool_value { "true".to_string() } else { "false".to_string() }; #+END_SRC ** Mutability and shadowing *** Immutable variable #+BEGIN_SRC rust let foo = 5; #+END_SRC *** Mutable variable #+BEGIN_SRC rust let mut bar = 5; bar = 6; #+END_SRC *** Shadowing #+BEGIN_SRC rust let baz = 5; let baz = baz + 3; #+END_SRC # ** Type aliases # The ~type~ keywoard declares an alias of another type. # *** Type aliases example # #+BEGIN_SRC rust # type Frequency = u64; # let clock: Frequency = 8_000_000 # #[allow(non_camel_case_types)] # type u64_t = u64; # let another_clock: Frequency = 16_000_000 as u64_t; # #+END_SRC ** Tuple structs *** Definition of a tuple struct #+BEGIN_SRC rust struct Rectangle(usize, usize); #+END_SRC *** Instantiation of a tuple struct #+BEGIN_SRC rust let rect = Rectangle(3, 5); #+END_SRC *** Access of a tuple struct's field #+BEGIN_SRC rust rect.0; rect.1; #+END_SRC ** Structs - Direct access vs. getter and setter (~pub~ keyword) - ~Something::new(item)~ and ~Something::default()~ *** Definition of a struct #+BEGIN_SRC rust struct Something { id: usize, item: String, } #+END_SRC ** Enums *** Enum example #+BEGIN_SRC rust enum Event { Receive, Send(String), Reset { address: u64, hard: bool }, } let new_event = Event::Send("A message".to_owned()); #+END_SRC ** Pattern matching and some macros @@latex:{\color{red}@@All match arms must return the same type!!1!@@latex:}@@ *** Simple ~match~ #+BEGIN_SRC rust match an_enum { MyEnum::Something => todo!("This has to be done"), MyEnum::SmthngElse(_) => unimplemented!("This is unimplemented"), MyEnum::AnotherThing(e) => println!("It is another thing: {}", e), _ => unreachable!(), }; #+END_SRC *** Assigning ~match~ #+BEGIN_SRC rust let maturity = match age { 0 | 1 => "infant", 2..=12 => "child", 13..=19 => "teen", _ => "...", }; #+END_SRC ** ~if let~ *** Simpler ~match~ #+BEGIN_SRC rust if let Some(inner_value) = foo { println!("Value: {}", inner_value); } else { println!("Nothing found"); } #+END_SRC ** Loops[fn:reference_loops] *** Loops - ~loop~: infinite loops - ~while~: loops until a predicate is false - ~while let~: loops until a pattern is matched - ~for~: loop over an iterator until it is empty *** Loop labels - ~break~: terminate/exit a loop - ~continue~: exit the current iteration and jump to the loop header ** Ownership /Ownership/ is one of Rusts central concepts to achieve memory safety without garbage collection. *** Ownership Rules - Each value has a variable that is called its /owner/. - There can only be one owner at a time. - When the owner goes out of scope, the value will be dropped. ** References - A value can temporarily borrowed from its owner without transferring ownership. - There can be multiple immutable references. - There can only be one mutable reference. - The ~&~ symbol is the reference operator. - The ~*~ symbol is the dereference operator. - References are immutable by default, use the ~mut~ keyword to make them mutable. ** Lifetimes - The Rust compiler (borrow checker) keeps track of how long references (borrows) are valid. - To ensure valid borrows and therefor prevent dangling borrows /Lifetimes/ are used. - /Lifetimes/ are annotations which tell the borrow checker how long a borrow needs to be valid. - /Lifetimes/ are implicit and inferred, that means the compiler infers /lifetimes/ wherever possible. - /Lifetimes/ must be annotated when the borrow checker cannot infer them on its own. *** Struct with /lifetimes/ #+BEGIN_SRC rust struct SomeApp<'a> { config: &'a Config, } #+END_SRC ** Error related types - Heavy use of ~Option~ and ~Result~ *** Option #+BEGIN_SRC rust pub enum Option { None, Some(T), } #+END_SRC *** Result #+BEGIN_SRC rust pub enum Result { Ok(T), Err(E), } #+END_SRC ** Error handling *** Unrecoverable errors \rightarrow panics #+BEGIN_SRC rust fn get_data() -> Data { ... panic!("Cannot get data"); } #+END_SRC *** Recoverable error with anyhow #+BEGIN_SRC rust fn get_data() -> Result { ... Ok(data) // return is only used for "early" returns } ... let data = get_data()?; ... #+END_SRC ** Printing When printing something, ~{}~ uses the ~std::fmt::Display~ trait and ~{:?}~ uses the ~std::fmt::Debug~ trait. *** ~print!()~ and ~println!()~ #+BEGIN_SRC rust let amount = 3; let fields = vec![0,2,5]; println!("We have {} of {:?}", amount, fields); #+END_SRC Prints: ~We have 3 of [0, 2, 5]~ ** Deriving ~Debug~ To enable printing of structs or enums when their fields implement ~Debug~ they can be derived with following annotation. *** Deriving ~Debug~ #+BEGIN_SRC rust #[derive(Debug)] struct Something { id: usize, item: String, } #+END_SRC ** Implementing ~Display~ *** Implementing ~Display~ #+BEGIN_SRC rust use std::fmt; struct Something { id: usize, item: String, } impl fmt::Display for Something { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}: {}", self.id, self.item) } } #+END_SRC ** Use functional paradigms - ~vec![1, 2, 3].iter()~ - ~vec![1, 2, 3].iter().sum()~ - ~vec![1, 2, 3].iter().map(|x| x + 1).collect()~ - ~foo.into_iter().filter(|i| i.bar == 0).collect()~ - ~Iterator~ trait ** Tests - Use ~assert!()~ family - Unit tests - Put them into a test module - Annotate the test module with ~#[cfg(test)]~ - Annotate the tests with ~#[test]~ - Documentation testing - Integration testing - Integration tests are put into the ~src/tests/~ directory - [[https://doc.rust-lang.org/book/ch11-00-testing.html][Rust Book: Writing Automated Tests]] - Alastair Reid: [[https://alastairreid.github.io/rust-testability/][Rust Design-for-Testability: a survey]] ** Documentation - Documentation comments: ~///~ - Markdown notation - ~cargo doc~ runns rustdoc which generates html docs - ~cargo doc --open~ runs rustdoc and opens the result in a browser - [[https://doc.rust-lang.org/rustdoc][rustdoc documentation]] ** FFI (Foreign Function Interface) - [[https://doc.rust-lang.org/nomicon/ffi.html][Rustonomicon: FFI]] - [[https://docs.rs/jni/][jni]]: Java bindings for Rust - [[https://bheisler.github.io/post/calling-rust-in-python/][Calling Rust From Python]] - [[https://github.com/rusterlium/rustler][Rustler]]: Write Erlang NIFs in Rust * Cargo ** Cargo #+BEGIN_CENTER \Huge *Cargo* #+END_CENTER #+ATTR_LaTeX: :height 0.4\textwidth [[./img/cargo.png]] ** What is it and how does it work? - Package manager - Build chain/tool - Cargo calls ~rustc~, the Rust compiler - A Cargo project contains at least one crate - Custom build scripts with ~build.rs~ - Builds just work ** Cargo commands *** Create a new binary crate (~init~ does so in an existing directory) #+BEGIN_SRC sh $ cargo new [--bin] #+END_SRC *** Create a new library crate (~init~ does so in an existing directory) #+BEGIN_SRC sh $ cargo new --lib #+END_SRC *** Update build dependencies #+BEGIN_SRC sh $ cargo update #+END_SRC *** Install crates #+BEGIN_SRC sh $ cargo install [crate] #+END_SRC ** Hello, World Executing ~`cargo new foobar`~ creates a new project... *** foobar/Cargo.toml #+BEGIN_SRC toml [package] name = "foo" version = "0.1.0" authors = ["finga "] edition = "2018" #+END_SRC \tiny #+BEGIN_SRC toml # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html #+END_SRC \normalsize #+BEGIN_SRC toml [dependencies] #+END_SRC *** foobar/src/main.rs #+BEGIN_SRC rust fn main() { println!("Hello, world!"); } #+END_SRC ** Docs - Cargo help: ~$ cargo --help~ and ~$ cargo [SUBCOMMAND] --help~ - [[https://doc.rust-lang.org/cargo/index.html][The Cargo Book]] (~$ rustup docs --cargo~) - Guillaume Gomez: [[https://blog.guillaume-gomez.fr/articles/2020-03-12+Guide+on+how+to+write+documentation+for+a+Rust+crate][Guide on how to write documentation for a Rust crate]] - [[https://crates.io/policies][Policies]] - [[https://crates.io/category_slugs][Category Slugs]] ** Cargo commands/plugins *** What I typically use - ~audit~: Audit ~Cargo.lock~ for security vulnerabilities. - ~bloat~: Identify which dependency adds how much bloat. - ~checkmate~: Run a list of checks (~check~, ~format~, ~build~, ~test~, ~doc~, ~audit~). - ~clippy~: Linter and static code analysis. - ~deb~: Automatically create a Debian package. - ~flamegraph~: Generate flamegraphs about anything. - ~fmt~: Format Rust code according to style guidelines. - ~install-update~: Keep all your Cargo commands/plugins up to date. *** @@comment: comment@@ Cargo downloads your Rust package's dependencies, compiles your package, makes distributable packages, and is able to upload them to [[https://crates.io][crates.io]], the Rust community's package registry. ** The Rust (package) registry *** Official registry [[https://crates.io][crates.io]] *** Unofficial [[https://crates.io][~crates.io~]] frontend [[https://lib.rs][lib.rs]] same but different.. * Setup ** Setup \Huge #+BEGIN_CENTER How to get all that stuff? #+END_CENTER ** Install the Rust-Toolchain *** Install the Rust toolchain ([[https://rustup.rs][~rustup.rs~]]) #+BEGIN_SRC sh $ curl --proto '=https' --tlsv1.2 -sSf \ https://sh.rustup.rs | sh #+END_SRC *** Rustup: The Rust toolchain installer - Check for new versions: ~$ rustup check~ - Update the toolchain: ~$ rustup update~ - Update rustup itself: ~$ rustup self update~ - Install Rust nightly (daily builds): ~$ rustup toolchain install nightly~ - Activate nightly globally: ~$ rustup default nightly~ - Activate nightly locally (in current dir): ~$ rustup override set nightly~ ** IDE support aka are we IDE yet?[fn:areweideyet] \tiny #+attr_latex: :align c|ccccccccc | | \rotatebox{90}{Syntax highlightning (.rs)} | \rotatebox{90}{Syntax highlightning (.toml)} | \rotatebox{90}{Snippets} | \rotatebox{90}{Code Completion} | \rotatebox{90}{Linting} | \rotatebox{90}{Code Formatting} | \rotatebox{90}{Go-to Definiton} | \rotatebox{90}{Debugging} | \rotatebox{90}{Documentation Tooltips} | |---------------------+--------------------------------------------+----------------------------------------------+--------------------------+---------------------------------+-------------------------+---------------------------------+---------------------------------+---------------------------+----------------------------------------| | Atom | X | X | X | X | X | X | X | | X | | Emacs | X | X | X | X | X | X | X | | X | | Sublime | X | X | X | X | X | X | X | | | | Vim/Neovim | X | X | X | X | X | X | X | | X | | VS Code | X | X | X | X | X | X | X | X | X | | BBedit | X | X | X | | | X | X | | | | Geany | X | | | | | | | | | | gedit | X | | | X | | | X | | | | Kakoune | X | X | X | X | X | X | X | | X | | Kate | X | X | | X | X | X | X | | | | Micro | X | X | | | X | X | | | | | Midnight Commander | X | | | | | | | | | | Textadept | X | X | X | X | X | | X | | | |---------------------+--------------------------------------------+----------------------------------------------+--------------------------+---------------------------------+-------------------------+---------------------------------+---------------------------------+---------------------------+----------------------------------------| | Eclipse | X | | X | X | X | X | X | X | X | | IntelliJ-based IDEs | X | X | X | X | X | X | X | X | X | | Visual Studio | X | | | X | | | X | X | | | GNOME Builder | X | | X | X | X | X | X | | | | Ride | X | | | | | | | | | * Common Crates ** General *** General - [[https://crates.io][crates.io]]/[[https://lib.rs][lib.rs]] - [[https://github.com/rust-unofficial/awesome-rust][Awesome Rust]] *** Misc. Crates - dotenv - [[https://tokio.rs/][tokio]] ** Parsing/Encoding - clap: The command line argument parser (use v3.0.0-beta when starting a new project) - [[https://serde.rs/][serde]] - nom - [[https://pest.rs/][pest]] ** Error handling - anyhow - thiserror - snafu - easy-error - eyre - color-eyre ** Logging - log: a lightweight logging facade - env_logger - simple_logger - simplelog - pretty_env_logger - stderrlog - flexi_logger - log4rs - fern - and many many more (checkout the log readme[fn:log_readme]) ** Testing - quickcheck - proptest - rutenspitz - [[https://rust-fuzz.github.io/book/cargo-fuzz.html][cargo-fuzz]] - [[https://rust-fuzz.github.io/book/afl.html][afl.rs]] - [[https://honggfuzz.dev/][honggfuzz-rs]] - arbitrary ** Data handling - lazy_static - once_cell (globality, singleton, lazy initialization) - static_assertions - [[http://plv.mpi-sws.org/rustbelt/ghostcell/][GhostCell]] ** Databases - [[https://indradb.github.io/][IndraDB]] - [[https://diesel.rs/][diesel]]: orm and query builder supporting - [[https://jmoiron.github.io/sqlx/][sqlx]] - refinery - barrel ** Tui - rustyline: Line editing library - tui: Library for ncurses like things - crossterm: Cross-platform terminal manipulation library ** Gui ([[https://www.areweguiyet.com/][areweguiyet.com]]) A small selection of crates I used/tried so far: - [[https://sixtyfps.io/][SixtyFPS]] (WASM support) - [[https://emilk.github.io/egui/][egui]] (WASM support) - imgui - [[https://gtk-rs.org/][gtk-rs]] - relm - [[https://bevyengine.org/][bevy_ui]] - and many many more ** WebDev [[https://www.arewewebyet.org/][Are we web yet]] - [[https://actix.rs/][Actix]] - [[https://hyper.rs/][Hyper]] - [[https://rocket.rs/][Rocket]] - reqwest ** Embedded - [[https://niclashoyer.github.io/areweembeddedyet/][Are we embedded yet]] - [[https://niclashoyer.github.io/areweembeddedyet/][Awesome Embedded Rust]] - [[https://docs.rust-embedded.org/embedonomicon/][Embedonomicon]] # - Microchip (Atmel) avr # - stm # - msp430 # - esp32 # - arm ** Unikernel For general information about unikernels visit [[https://unikernel.org][unikernel.org]]. - [[https://github.com/hermitcore/rusty-hermit][RustyHermit]] ** Thats it for now \Large #+BEGIN_CENTER Thank you for your attention! Questions? #+END_CENTER \normalsize *** To be continued **** Column left :PROPERTIES: :BEAMER_col: 0.45 :END: - Traits - Generics - Type Aliases vs. New Type Idioms - Ownership - References and Slices - Lifetimes - Iterators - Functional paradigms **** Column right :PROPERTIES: :BEAMER_col: 0.45 :END: - Metaprogramming (macros) - (Smart) Pointers - Concurrency - Object Oriented Programming - Closures - Async-Await - ~unsafe~ Rust * Footnotes [fn:rust_fungus] [[https://commons.wikimedia.org/wiki/File:Bruine_roest_op_tarwe_(Puccinia_recondita_f.sp._tritici_on_Triticum_aestivum).jpg][Wikimedia]] (Puccinia recondita f.sp. tritici) [fn:strengths] Copied list from: [[https://cheats.rs/#tab-hello-3][cheats.rs]]. [fn:weaknesses] Copied list from: [[https://cheats.rs/#tab-hello-4][cheats.rs]]. [fn:lwn_gcc] [[https://lwn.net/Articles/871283/][Rust and GCC, two different ways]] [fn:gcc] Work on GCC: [[https://rust-gcc.github.io/][rust-gcc]] and [[https://news.ycombinator.com/item?id=27775544][gcc rust backend]]. [fn:survey] [[https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html#why-not-use-rust][Rust survey]] [fn:compiler_speed] [[https://news.ycombinator.com/item?id=23538220][The Rust compiler isn't slow; we are]] [fn:specification] [[https://people.mpi-sws.org/%7Ejung/thesis.html][Understanding and Evolving the Rust Programming Language]] [fn:xkcd_dangling_pointer] [[https://xkcd.com/371/][xkcd.com/371]] [fn:reference_loops] [[https://doc.rust-lang.org/reference/expressions/loop-expr.html][Rust Reference: Loops]] [fn:areweideyet] [[https://areweideyet.com/][areweideyet.com]] [fn:log_readme] https://github.com/rust-lang/log#in-executables