# The Borrow Checker Is Not The Problem: Introducing `Cowboy`
In the post [Leaving Rust gamedev after 3 years](https://loglog.games/blog/leaving-rust-gamedev/#once-you-get-good-at-rust-all-of-these-problems-will-go-away), the author says this:
> The most fundamental issue is that the borrow checker forces a refactor at the most inconvenient times.
I just wanted to point out one thing. The Borrow Checker is not the root cause of the problem, when comparing Rust to other languages like C#.
**The Borrow Checker**: Ensures references don't outlive their data. (The borrow checker can theoretically be bypassed with `unsafe`.)
**The Memory Model**: Rust uses RAII - objects are freed immediately when they go out of scope. This differs from garbage-collected languages like C# where objects live as long as references exist.
The core problem isn't just the borrow checker, it's the memory model. Even without the borrow checker, you'd still need to refactor code when objects need to live longer, because you'd have to explicitly extend their scope. Garbage collection is more flexible because it automatically keeps objects alive as long as they're referenced.
So the "forced refactors" that Rust users experience aren't just about satisfying the borrow checker. They're fundamentally about moving objects to the right scope for the program's lifetime requirements. Using `unsafe` alone wouldn't solve this.
However, you can relax Rust's memory model a bit using `Arc` and `RwLock`. `Arc` just makes a variable reference-counted, so it gets freed when there are no more references to it. `RwLock` essentially implements the Rust borrow checker's rules at runtime instead of compile time, so you get all the safety at some mild performance cost.
The worst part about this is that you have to write `Arc<RwLock<T>>` everywhere. This is why I created the [Cowboy](https://crates.io/crates/cowboy) library:
```rust
use cowboy::*;
// use `.cowboy()` on any value to get a Cowboy version of it.
let counter = 0.cowboy();
println!("Counter: {counter}");
// Cloning a cowboy gives you a pointer to the same underlying data
let counter_2 = counter.clone();
// Modify the value
*counter.w() += 1;
// Both counter and counter_2 were modified
assert_eq!(counter, counter_2);
```
```rust
use cowboy::*;
let counter = 0.cowboy();
// You can register cowboys with the SHERIFF using any key type
SHERIFF.register("counter", counter.clone());
SHERIFF.register(42, counter.clone());
// Access from anywhere
let counter_1 = SHERIFF.get::<_, i32>("counter");
let counter_2 = SHERIFF.get::<_, i32>(42); // Note: not &42
*counter_1.w() += 1;
*counter_1.w() += 2;
*counter_2.w() += 3;
// All counters should have the same value since they're all clones of the same original counter
assert_eq!(counter_1, counter_2);
println!("Counter: {counter}");
```
`Cowboy<T>` is just a wrapper for `Arc<RwLock<T>>` that's designed to be as low-boilerplate as possible. It has more concise method names, and lots of trait implementations that make it work in more cases (you can use `Eq`, `Hash`, `Ord`, and so on as long as the underlying type supports it).
Cowboy values can be shared between threads, modified from multiple places, and so on, all without ever worrying about the borrow checker.
The library also provides `SHERIFF`, which can be used to store and access `Cowboy` values globally. I think we can all agree that you shouldn't use `Cowboy` or `SHERIFF` in production code, but I'm hopeful it can be useful for when you're prototyping and want the borrow checker to get out of your way.