<commit_before># Threads, Networking and Sharing

## Changing the Unchangeable

If you're feeling pig-headed (as I get) you wonder if it's _ever_ possible to get
around the restrictions of the borrow checker.

Consider the following little program, which compiles and runs without problems.

```rust
// cell.rs
use std::cell::Cell;

fn main() {
    let answer = Cell::new(42);

    assert_eq!(answer.get(), 42);

    answer.set(77);

    assert_eq!(answer.get(), 77);
}
```

The answer was changed - and yet the _variable_ `answer` was not mutable!

This is obviously perfectly safe, since the value inside the cell is only accessed
through `set` and `get`.  This goes by the grand name of _interior mutability_. The
usual is called _inherited mutability_: if I have a struct value `v`, then I can only
write to a field `v.a` if `v` itself is writeable. `Cell` values relax this rule, since
we can change the value contained within them with `set` even if the cell itself is
not mutable.

However, `Cell` only works with values that can be copied, that is, they implement `Copy`,
like primitive types and structs containing them marked as 'derive(Copy)'.

For other values, we have to get a reference we can work on, either mutable or immutable.
This is what `RefCell` provides - you ask it explicitly for a reference to the contained
value:

```rust
// refcell.rs
use std::cell::RefCell;

fn main() {
    let greeting = RefCell::new("hello".to_string());

    assert_eq!(*greeting.borrow(), "hello");
    assert_eq!(greeting.borrow().len(), 5);

    *greeting.borrow_mut() = "hola".to_string();

    assert_eq!(*greeting.borrow(), "hola");
}
```
The explicit dereference operator `*` can be a little bit confusing in Rust, because
often you don't need it - for instance `greeting.borrow().len()` is fine since method
calls will deference implicitly.  But you _do_ need `*` to pull out the underlying
`&String` from `greeting.borrow()` or the `&mut String` from `greeting.borrow_mut()`.

Using a `RefCell` isn't always safe, because any references returned from these
methods must follow the usual rules.


```rust
    let mut gr = greeting.borrow_mut(); // gr is a mutable borrow
    *gr = "hola".to_string();

    assert_eq!(*greeting.borrow(), "hola"); // <== we blow up here!
....
thread 'main' panicked at 'already mutably borrowed: BorrowError'
```

You cannot borrow immutably if you have already borrowed mutably! Except - and this
is important - the violation of the rules happens at _runtime_.  The solution (as always)
is to keep the scope of mutable borrows as limited as possible - in this case, you could
put a block around the first two lines here so that the mutable reference `gr` gets
dropped before we borrow again.

So, this is not a feature you use without good reason, since you will _not_ get a
compile-time error.  These types provide _dynamic borrowing_ in cases where the usual
rules make some things impossible.<commit_msg>Issue #41: rewording of Cell discussion, typo fix<commit_after># Threads, Networking and Sharing

## Changing the Unchangeable

If you're feeling pig-headed (as I get) you wonder if it's _ever_ possible to get
around the restrictions of the borrow checker.

Consider the following little program, which compiles and runs without problems.

```rust
// cell.rs
use std::cell::Cell;

fn main() {
    let answer = Cell::new(42);

    assert_eq!(answer.get(), 42);

    answer.set(77);

    assert_eq!(answer.get(), 77);
}
```

The answer was changed - and yet the _variable_ `answer` was not mutable!

This is obviously perfectly safe, since the value inside the cell is only accessed
through `set` and `get`.  This goes by the grand name of _interior mutability_. The
usual is called _inherited mutability_: if I have a struct value `v`, then I can only
write to a field `v.a` if `v` itself is writeable. `Cell` values relax this rule, since
we can change the value contained within them with `set` even if the cell itself is
not mutable.

However, `Cell` only works with `Copy` types
(e.g primitive types and user types deriving the `Copy` trait).

For other values, we have to get a reference we can work on, either mutable or immutable.
This is what `RefCell` provides - you ask it explicitly for a reference to the contained
value:

```rust
// refcell.rs
use std::cell::RefCell;

fn main() {
    let greeting = RefCell::new("hello".to_string());

    assert_eq!(*greeting.borrow(), "hello");
    assert_eq!(greeting.borrow().len(), 5);

    *greeting.borrow_mut() = "hola".to_string();

    assert_eq!(*greeting.borrow(), "hola");
}
```

Again, `greeting` was not declared as mutable!

The explicit dereference operator `*` can be a bit confusing in Rust, because
often you don't need it - for instance `greeting.borrow().len()` is fine since method
calls will dereference implicitly.  But you _do_ need `*` to pull out the underlying
`&String` from `greeting.borrow()` or the `&mut String` from `greeting.borrow_mut()`.

Using a `RefCell` isn't always safe, because any references returned from these
methods must follow the usual rules.

```rust
    let mut gr = greeting.borrow_mut(); // gr is a mutable borrow
    *gr = "hola".to_string();

    assert_eq!(*greeting.borrow(), "hola"); // <== we blow up here!
....
thread 'main' panicked at 'already mutably borrowed: BorrowError'
```

You cannot borrow immutably if you have already borrowed mutably! Except - and this
is important - the violation of the rules happens at _runtime_.  The solution (as always)
is to keep the scope of mutable borrows as limited as possible - in this case, you could
put a block around the first two lines here so that the mutable reference `gr` gets
dropped before we borrow again.

So, this is not a feature you use without good reason, since you will _not_ get a
compile-time error.  These types provide _dynamic borrowing_ in cases where the usual
rules make some things impossible.
{'fraction_non_alphanumeric': 0.09608240459304289, 'fraction_numerical': 0.003377237419790611, 'mean_word_length': 4.195614035087719, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5875798', 'n_tokens_mistral': 1763, 'n_tokens_neox': 1698, 'n_words': 826}