diff --git a/img/compiler_complaint.png b/img/compiler_complaint.png deleted file mode 100644 index 7296d07..0000000 --- a/img/compiler_complaint.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0467e6d0e9c81afea4164d28def71999233b3848868c60425c8838c0998270dd -size 32187 diff --git a/rust-intro.org b/rust-intro.org index a53354e..f15904b 100644 --- a/rust-intro.org +++ b/rust-intro.org @@ -5,11 +5,11 @@ #+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 +#+DATE: \today #+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. +#+DESCRIPTION: #+LANGUAGE: en #+KEYWORDS: rust programming #+SELECT_TAGS: export @@ -18,7 +18,6 @@ #+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 @@ -26,23 +25,25 @@ #+BEAMER_FONT_THEME: #+BEAMER_INNER_THEME: #+BEAMER_OUTER_THEME: +#+LaTeX_CLASS_OPTIONS: [smaller] * 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] + [fn:1] #+END_CENTER *** Rust, the language - - First appearance 2010 - - Rust is the coating closest to the bare metal + - A bit more than 10 years old (2010) - Memory safe without gcing, optional reference counting - - Ownership, lifetimes, traits, functional paradigms, zero-cost - and zero-size abstractions + - Ownership, lifetimes, traits, functional paradigms + - Variables are immutable by default and can be shadowed + - Performance of idiomatic Rust is comparable to the performance + of idiomatic C++ - A well designed language and ecosystem -** Strengths and Weaknesses[fn:strengths] +** Strengths and Weaknesses[fn:2] *** 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]]. @@ -51,37 +52,24 @@ - 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:gcc] + LLVM).[fn:3] - [[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] +** Strengths and Weaknesses[fn:2] *** Points you might run into (Weaknesses) - - Steep learning curve[fn:survey] compiler enforcing (esp. memory) + - Steep learning curve[fn:4] 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] + (esp. embedded), IDE features.[fn:4] - Longer compile times than "similar" code in other - languages.[fn:survey][fn:compiler_speed] + languages.[fn:4][fn:5] - No formal language specification, can prevent legal use in some - domains (aviation, medical, ...).[fn:specification] + domains (aviation, medical, ...).[fn:6] - Careless (use of ~unsafe~ in) libraries can secretly break safety guarantees. -** Problems and security 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]] @@ -89,276 +77,23 @@ - [[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~) + - [[https://doc.rust-lang.org/nomicon/][The Rustonomicon]]: About unsafe Rust (~$ rustup docs --nomicon~) - Use '~$ rustup help docs~' to get an overview -*** Other helpful sites +*** Helpful sites - [[https://cheats.rs][cheats.rs]] - [[https://programming-idioms.org/cheatsheet/Rust][programming-idioms.org]] -** 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]] (Not only for Rust, but it is also supported) - +** Where to find help and stay up to date *** 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 +*** Boards/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 - - Functional paradigms - - Pattern matching - - Memory safety - - 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()~ -*** 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 -*** 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 - -** ~if let~ - -** Pattern matching and some macros -*** Simple ~match~ - #+BEGIN_SRC rust - match an_enum { - MyEnum::Something => todo!("This has to be done"), - MyEnum::SomethingElse(_) => unimplemented!("This is not implemented"), - 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 - -** 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 - -** 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 more functional language features - - ~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 @@ -368,43 +103,13 @@ #+ATTR_LaTeX: :height 0.4\textwidth [[./img/cargo.png]] -** What is it and how does it work? +** What is it? - Package manager - - Build chain/tool - - Cargo calls ~rustc~, the Rust compiler - - A Cargo project contains at least one crate - -** 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 + - Build tool + - A Cargo project contains least one crate ** Docs - [[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]] ** Cargo commands/plugins *** What I typically use @@ -413,32 +118,13 @@ - ~checkmate~: Run a list of checks (~check~, ~format~, ~build~, ~test~, ~doc~, ~audit~). - ~clippy~: Linter and static code analysis. - - ~deb~: Automatically create a Debian package. + - ~deb~: Automatically create a binary Debian package. + - ~edit~: Modify your ~Cargo.toml~ from the command line. - ~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 uploads 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.. + - ~install-update~: Keep all your Cargo commands up to date. * Setup -** Setup - \Huge - #+BEGIN_CENTER - How to get all that stuff? - #+END_CENTER - ** Install the Rust-Toolchain *** Install Rust From [[https://rustup.rs][rustup.rs]]: @@ -454,115 +140,34 @@ - Activate nightly locally (in current dir): ~$ rustup override set nightly~ -** Handle the Rust toolchain with ~rustup~ +* Hands on -*** 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 +* Testing -*** Update ~rustup~ - #+BEGIN_SRC sh - $ rustup self update - #+END_SRC +* Documentation -*** Check for updates for installed toolchains - #+BEGIN_SRC sh - $ rustup check - #+END_SRC +* IDE support + [[https://areweideyet.com/][Are we IDE yet]] -*** Update toolchains if outdated - #+BEGIN_SRC sh - $ rustup update - #+END_SRC - -** IDE support aka are we IDE yet?[fn:areweideyet] - \tiny -| | \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 +* (Standard?) crates - [[https://crates.io][crates.io]]/[[https://lib.rs][lib.rs]] - [[https://github.com/rust-unofficial/awesome-rust][Awesome Rust]] + - clap (command line argument parser) + - env_logger, log - dotenv - - [[https://tokio.rs/][tokio]] - -** Parsing/Encoding - - clap: The command line argument parser (if starting a new project - I would use v3.0.0-beta) - - [[https://serde.rs/][serde]] + - serde + - lazy_static, once_cell (globality, singleton, lazy initialization) - nom - - [[https://pest.rs/][pest]] - -** Error handling - - anyhow - - thiserror - - snafu - - easy-error - -** 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 - -** Data handling - - lazy_static - - once_cell (globality, singleton, lazy initialization) - - [[http://plv.mpi-sws.org/rustbelt/ghostcell/][GhostCell]] + - tokio ** Databases - - [[https://indradb.github.io/][IndraDB]] - - [[https://diesel.rs/][diesel]]: orm and query builder supporting - sqlx - - refinery - - barrel - -** Gui ([[https://www.areweguiyet.com/][areweguiyet.com]]) - A small selection of crates I used/tried so far: - - SixtyFPS - - egui - - imgui - - GTK - - relm - - and many many more - - bevy_ui + - diesel ** WebDev [[https://www.arewewebyet.org/][Are we web yet]] + - Actix - Hyper - Rocket @@ -573,26 +178,15 @@ [[https://niclashoyer.github.io/areweembeddedyet/][Awesome Embedded Rust]] [[https://docs.rust-embedded.org/embedonomicon/][Embedonomicon]] - # - Microchip (Atmel) avr - # - stm - # - msp430 - # - esp32 - # - arm - -** Unikernel - https://unikernel.org - - - [[https://github.com/hermitcore/rusty-hermit][RustyHermit]] + - avr + - stm + - msp430 + - esp32 * Footnotes -[fn:rust_fungus] [[https://commons.wikimedia.org/wiki/File:Bruine_roest_op_tarwe_(Puccinia_recondita_f.sp._tritici_on_Triticum_aestivum).jpg][Wikimedia]] -[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: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 +[fn:1] [[https://commons.wikimedia.org/wiki/File:Bruine_roest_op_tarwe_(Puccinia_recondita_f.sp._tritici_on_Triticum_aestivum).jpg][Wikimedia]] +[fn:2] Copied from: https://cheats.rs. +[fn:3] Work on GCC: [[https://rust-gcc.github.io/][rust-gcc]] and [[https://news.ycombinator.com/item?id=27775544][gcc rust backend]]. +[fn:4] [[https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html#why-not-use-rust][Rust survey]] +[fn:5] [[https://news.ycombinator.com/item?id=23538220][The Rust compiler isn't slow; we are]] +[fn:6] [[https://people.mpi-sws.org/%7Ejung/thesis.html][Understanding and Evolving the Rust Programming Language]]