diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1525076..10a3782 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -47,7 +47,7 @@ - [Generics](ch10-00-generics.md) - [Syntax](ch10-01-syntax.md) - - [Traits](ch10-02-traits.md) + - [Traits](ch10-02-traits.md) - NEED DEFAULT METHOD IMPLEMENTATIONS - [Lifetime syntax](ch10-03-lifetime-syntax.md) - [Testing](ch11-00-testing.md) @@ -56,58 +56,26 @@ - [Test Organization](ch11-03-test-organization.md) - [I/O]() - - [`Read` & `Write`]() - - [`std::fs`]() - - [`std::path`]() - - [`std::env`]() - ## Thinking in Rust -- [Thinking in Rust]() - - [Instead of Inheritance]() - - [Trait Objects?]() +- [Functional Language Features in Rust - Iterators and Closures](ch13-00-functional-features.md) -- [Creating a Library]() - - [Cargo]() - - [Crates.io]() - - [Organizing your Public API](chYY-YY-public-api.md) - - [Documentation](chYY-YY-documentation.md) - - [Workspaces and Multiple Related Crates](chYY-YY-workspaces.md) +- [More about Cargo and Crates.io](ch14-00-more-about-cargo.md) -- [Closures]() +- [Smart Pointers](ch15-00-smart-pointers.md) -- [Zero-cost Abstractions]() - - [Iterators as a Case Study]() +- [Concurrency](ch16-00-concurrency.md) -- [Smart Pointers]() - - [`Box`]() - - [`Rc`]() - - [`Cell`]() - - [`RefCell`]() - - [Interior Mutability]() - -- [Concurrency](ch18-00-concurrency.md) - - [Threads]() - - [`Send` & `Sync`]() - - [`Arc`]() - - [`Mutex`]() - - [`Channels`]() +- [Is Rust OOP?](ch17-00-oop.md) ## Advanced Topics -- [Patterns](chXX-patterns.md) +- [Patterns](ch18-00-patterns.md) (perhaps an appendix?) -- [More Lifetimes]() +- [More Lifetimes](ch19-00-more-lifetimes.md) (perhaps merge this into advanced type system features?) -- [Unsafe Rust]() (think about merging into the next chapter on advanced type system features) - - [Raw Pointers]() - - [`transmute`]() - -- [Advanced Type System Features]() (perhaps called "Advanced Traits"?) - - [Associated Types]() - - [UFCS]() - - [Coherence]() +- [Advanced Type System Features](ch20-00-advanced-types.md) (perhaps called "Advanced Traits"?) - [Macros]() (think about making little book of rust macros the authority on this topic) - [Writing Your Own Macros]() diff --git a/src/appendix-04-nightly-rust.md b/src/appendix-04-nightly-rust.md new file mode 100644 index 0000000..f99a3f3 --- /dev/null +++ b/src/appendix-04-nightly-rust.md @@ -0,0 +1 @@ +# Nightly Rust diff --git a/src/ch13-00-functional-features.md b/src/ch13-00-functional-features.md new file mode 100644 index 0000000..9269638 --- /dev/null +++ b/src/ch13-00-functional-features.md @@ -0,0 +1,39 @@ +# Functional Language features in Rust - Iterators and Closures + +## Closures + +### What is a closure + +How are they diff from fns + +### `Fn` traits + +## Iterators + +### Iterator & for loop + +.into_iter() + +### Iterators are Lazy + +Difference between adapter and consumer - another iterator or consuming? + +### Implementing the Iterator trait + +Talk about using Associated Types here, foreshadow to advanced type systems +chapter about why this is a different thing than normal + +## ??? How does this improve `greprs` + +Does this get woven into the above sections? + +## Summary: Performance + +### Iterators compile down to ASM == for loop + +Most complicated chain of iterator functions that compile down to the same ASM as a for loop + +### Representation: Closures are a Struct + +Closures don't have any further perf penalty over regular fn calls + diff --git a/src/ch15-00-smart-pointers.md b/src/ch15-00-smart-pointers.md new file mode 100644 index 0000000..5273b49 --- /dev/null +++ b/src/ch15-00-smart-pointers.md @@ -0,0 +1,112 @@ +# Smart Pointers + +By smart pointers we mean a reference with more characteristics. + +Example of something that doesn't work + +Surprise! Vec and String are technically smart pointers too! + +This chapter is not a comprehensive list, but will give some examples of the +ones in the standard library. + + +## `Box` + +Don't use very often in your own code +Heap allocated +Express Ownership of a heap allocated thing + +The three situations to use Box + +1. Trait objects +2. Recursive data structures +3. Extend the lifetime of something + +How this interacts with the Drop trait + +## `Rc` + +Reference counted. Rc is for *multiple ownership* - this thing should get +deallocated when all of the owners go out of scope. + +Show the data structure: + +```rust +struct Rc { + data: Box, + strong_reference_count: usize, + weak_reference_count: usize, +} +``` + +Talk through this. + +This only works if the data is immutable. + +What happens when you clone an Rc: data isn't cloned, increase the strong count. +When an Rc clone goes out of scope, the count goes down. + +### Rc Cycles + +This is how you leak memory in rust, which btw is totally safe. + +Is this garbage collecting? Well it's not tracing GC... if you use Rc and had +a cycle detector, it would be functionally equivalent to a tracing GC. Different +runtime characteristics tho. + + +#### Solution: turn an Rc into a `Weak` + +Same as Rc, but doesn't count towards the strong ref count. When you do this, the +strong ref count goes down and the weak count goes up. + +Data gets cleaned up when the strong count is 0, no matter what the weak count is. + +Why is the weak count needed then???? + + +## `RefCell` + +Single owner of mutable data + +The ownership rules checked at runtime instead of compile time. + +Only single threaded. See next chapter. + +### `borrow` and `borrow_mut` methods + +Checks all the rules and panics at runtime if the code violates them. + +1. The borrow checker is conservative and people can know more things. (no you +don't, but if you really want to go back to debugging segfaults, feel free) + +2. For when you're only allowed to have an immutable thing (which could be `Rc`) +but you need to be able to mutate the underlying data. + +## `Cell` + +Same thing as RefCell but for types that are Copy. No borrow checking rules here +anyway. So just reason #2 above. + +## Is this really safe? Yes srsly + +RefCell is still doing the checks, just at runtime +Cell is safe bc Copy types don't need the ownership rules anyway + +### The Interior Mutability Pattern + +The Interior Mutability Pattern is super unsafe internally but safe to use +from the outside and is totally safe, totally, trust us, seriously, it's safe. + +Allude to `UnsafeCell` maybe. Affects optimizations since &mut T is unique. +UnsafeCell turns off those optimizations so that everything doesn't break. + +This is how you can opt-out of the default of Rust's ownership rules and opt +in to different guarantees. + +## Summary + +If you want to implement your own smart pointer, go read the Nomicon. + +Now let's talk about concurrency, and some smart pointers that can be used +with multiple threads. diff --git a/src/ch18-00-concurrency.md b/src/ch16-00-concurrency.md similarity index 64% rename from src/ch18-00-concurrency.md rename to src/ch16-00-concurrency.md index 9c32ee7..9bed80f 100644 --- a/src/ch18-00-concurrency.md +++ b/src/ch16-00-concurrency.md @@ -1,17 +1,101 @@ -# Concurrency - -This is a really rough sketch of some ideas that this chapter might cover. - -From a comment of steveklabnik's on [the orange website]. "that paper" refers to [Boehm 2004]. - -[the orange website]: https://news.ycombinator.com/item?id=13078384 -[Boehm 2004]: http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf +# Fearless Concurrency So, with Rust, it's more subtle than that. That is, while threading proper isn't part of the language itself, Rust's type system is structured in such a way as to make it possible to build those kinds of libraries. In other words, Rust's focus on aliasability ends up solving these problems. +This is a library abstraction. + +Shared mutable state is a problem. Both useful. Functional langs get rid of +mutability. + +Ownership rules (that tame the "shared" aspect) enable fearless concurrency: the +compiler is making sure you don't shoot yourself in your foot. + +## What are threads + + + +## Rust's concurrency tradeoffs + +Lots of different languages tackle this problem in different ways. We are not +going to talk about that: exercise for the reader is investigate other langs +and compare and contrast with Rust's approach. + +This is how Rust does it, what rust means by threads + +OS threads are exposed in the standard library bc a systems programming language +should integrate with your system. + +If you have a different threaded mechanism, you need a runtime, rust is trying +to not have a heavy runtime. + +These are the reasons Rust's concurrency model is this way as opposed to other +lang's ways, which are optimizing for different things. + + +## Let's get a thread: `thread::spawn` + +Code examples - just print stuff, no data sharing + +## Communicating between threads + +### `Channels` + +Look up examples of cases where channels are useful + +Can match modeling of certain problems + +#### `Send` + +Send is a trait that means i'm allowed to transfer ownership to another thread +down a channel + +What things can be send and what can't? + +## Sharing data between threads + +Try to share data and get an error about which trait it doesn't implement + +### `Sync` + +It's ok to access a thing from multiple threads at once + +Immutable things can be sync easily. + +### `Arc` + +Atomic Reference Counting. Inner data still has to be immutable. + +Steve knows the motivating code that goes here. + +### `Mutex` + +For mutabe data. + +`lock` method, you get a Mutex guard. Change, then unlock, which usually happens +automatically when the Mutex guard goes out of scope. If you do this wrong, your +code will hang. + +Deadlocks are safe, you have to manage that yourself. Deadlock bugs usually +happen bc you forget to unlock, but drop unlocks automatically. + + +## Maybe make `greprs` concurrent? + +Might be boilerplatey without scoped threads, maybe just allude. + + + +This is a really rough sketch of some ideas that this chapter might cover. + +From a comment of steveklabnik's on [the definitely not orange website]. "that paper" refers to [Boehm 2004]. + +[the orange website]: https://news.ycombinator.com/item?id=13078384 +[Boehm 2004]: http://www.hpl.hp.com/techreports/2004/HPL-2004-209.pdf + + So for example, in that paper, 4.1 is about the problem of concurrent modifiability. And indeed, it says diff --git a/src/ch17-00-oop.md b/src/ch17-00-oop.md new file mode 100644 index 0000000..7d0018e --- /dev/null +++ b/src/ch17-00-oop.md @@ -0,0 +1,73 @@ +# Is Rust OOP? + +Aphorism: DRY + +So how do you share code? + +I'm used to doing things to solve problems, what do i do instead? +Why do i need to do different things in Rust? Let's look at an example +with the Command pattern. + +## Command pattern + +Look up official def + +Want caller to be able to customize what gets done + +Method takes command object, calls a run fn + +How do we say "we want a thing that has a run function"? Answer: Traits! + +where T: Run + +This is the definition of the Fn trait! So we wouldn't implement this, we'd just +pass closures in + +## Supertraits + +Trait constraints that use other traits + +Copy requires Clone because Copy is a subset of Clone's behavior, since if you +have one, you can trivially implement the other. + +Traits that need behavior of another trait in a default method or something. + +## Trait objects + +Runtime decisions about deciding what shared code we use + +Give example code + +With traits, libraries are extendable. This is why trait objects are different +than having an enum and a match statement that has to be exhaustive at compile +time and we have to know all the things at compile time and no one can add +new things to the set of possible things + +T: trait is a compile time decision, monomorphization == static dispatch + +when you implement this trait, you get this other shared behavior + +dynamic dispatch (C++) + +### Implementation details + +- Like how other languages implement oo. + +### How to use it + +- Statically checked duck typing + +## Builder pattern + +When you don't know how many arguments you're going to have + +## Delegation + +Deref - be mad + +Deref is a way to delegate everything, if you don't want that, then write +boilerplate. Sending messages to your components. + +## How do you share data? + +Answer: get and set methods, this is awkward and might get better someday. diff --git a/src/chXX-patterns.md b/src/ch18-00-patterns.md similarity index 100% rename from src/chXX-patterns.md rename to src/ch18-00-patterns.md diff --git a/src/ch19-00-more-lifetimes.md b/src/ch19-00-more-lifetimes.md new file mode 100644 index 0000000..535e161 --- /dev/null +++ b/src/ch19-00-more-lifetimes.md @@ -0,0 +1,11 @@ +# More Lifetimes + +## Lifetimes that depend on other lifetimes + +'a: 'b stuff: subtyping + +## Higher ranked trait bounds + +for<'a> + +Needed for closures diff --git a/src/ch20-00-advanced-types.md b/src/ch20-00-advanced-types.md new file mode 100644 index 0000000..51f4899 --- /dev/null +++ b/src/ch20-00-advanced-types.md @@ -0,0 +1,56 @@ +# Advanced Type System Features + +## Unsafe Rust + +Things you may do in an unsafe block that you may not in safe rust + +- deref a raw pointer +- call an unsafe fn +- access or modify a static variable +- impl an unsafe trait + +Go see other stuff + +Here's the syntax tho + +You know unsafe blocks are the cause of any crashes + +wrap all the unsafe, make it as small as possible, present a safe public API + +### Raw Pointers + +### Unsafe Functions + +#### `transmute` + +never ever. don't. stop. + +#### `extern fn` + +You have to write unsafe code to FFI + +### `static` + +### Unsafe Traits + +## Associated Types + +More common than the other things, less common than the rest of the book + +why this is a thing instead of a generic + +## The Thing Formerly Known as UFCS + +Only needed when implementing super generic code + +Lots of things are syntax sugar for this + +Two traits that impl the same method - how to disambiguate + +## Coherence + +Show examples of when you control traits and types or not + +Ex: Cannot impl Debug on someone else's type + +Solution: newtype