My least favorite bugs are usually caused by:
- Thread races
- Aliased memory
While Rust doesn’t fill the same niche as Julia with respect to scientific computing, I really like the safety guarantees around ownership and borrow checker. At the expense of flexibility of code, the model provides some formal guarantees about thread races and mutability.
I’m therefore wondering if there is any Julia package that can help provide guarantees for these sorts of issues? The dream is to have some kind of compiler flag to do scope analysis similar to Rust:
fn main() {
let mut x = 42;
let ref1 = &x; // Immutable borrow
let ref2 = &mut x;
// ERROR: cannot borrow `x` as mutable because
// it is also borrowed as immutable
println!("ref1: {}", ref1);
}
Rust literally refuses to compile this, and the static analysis tool points it out:
I think it would be awesome if Julia itself eventually had an opt-in system that could do borrow checking and ownership like this. But I of course understand such a thing would take a lot of work.
In the meantime I’m wondering if there are any packages available for this sort of thing? I’m looking for something like this –
@borrow_checker function main()
@safe :mut x = 42
# Borrow x as an immutable reference:
ref1 = @ref x # defaults to :immutable
# Attempt to borrow x as a mutable reference:
ref2 = @ref :mut x
# ^This should error because ref1 is still active
println(ref1[])
end
-
@borrow_checker
A macro that does a “function-wide” analysis and unwrapping (either purely syntactic or some combination of syntactic + runtime checks). I think this would basically unwrapx
at function call sites so that external functions don’t need to accommodate aSafe{T}
type. But it would only unwrap a variable once - so it can’t be owned by multiple scopes. -
@safe
Tells the@borrow_checker
to track it. Wraps an object (like Ref(1) or an Array) in a “tracked” container that knows how many mutable/immutable borrows currently exist. -
@ref
Extracts either an immutable reference or a mutable reference. If a mutable reference is requested (with:mut
) but an immutable one is still active, we fail. Similarly, if a mutable reference is active, we can’t even create an immutable reference.
Edit: see updated syntax later in thread
I guess it should really go into the compiler though. It would also permit additional optimizations if the compiler knows a given variable will not be mutated in a given scope – especially things like arrays.
Maybe a JET-style approach could work as well.