Really rough outline notes

This commit is contained in:
Carol (Nichols || Goulding) 2016-12-26 19:35:13 -05:00
parent 948b1b4177
commit 817d64276b
9 changed files with 393 additions and 49 deletions

View File

@ -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<T>`]()
- [`Rc<T>`]()
- [`Cell`]()
- [`RefCell`]()
- [Interior Mutability]()
- [Concurrency](ch18-00-concurrency.md)
- [Threads]()
- [`Send` & `Sync`]()
- [`Arc<T>`]()
- [`Mutex<T>`]()
- [`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]()

View File

@ -0,0 +1 @@
# Nightly Rust

View File

@ -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

View File

@ -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<T>`
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<T>`
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<T> {
data: Box<T>,
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<T>`
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<T>`
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<T>`
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<T>` 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.

View File

@ -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<T>`
Atomic Reference Counting. Inner data still has to be immutable.
Steve knows the motivating code that goes here.
### `Mutex<T>`
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

73
src/ch17-00-oop.md Normal file
View File

@ -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.

View File

@ -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

View File

@ -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