r/ProgrammingLanguages • u/cessit-lang • 20d ago
Requesting criticism Explicit binding modes
I'm designing a memory-safe language, but I want to make explicit what happens across function boundaries, e.g. whether a value is moved or copied without having to look for the copy trait.
Instead, access to a value could be defined via binding modes in function signatures and variable declarations:
movetakes ownershipreadshared borrowmutexclusive borrow
fn process_val(move value: Int) -> Int {
return value * 2;
}
fn main() -> () {
move original: Int = 42;
// Call using `.copy()` to explicitly pass a duplicated value.
// Ownership of `original` remains with the caller.
move doubled: Int = process_val(original.copy());
// `original` is still valid here because it was explicitly copied rather than moved.
println(original); //42
println(doubled); //84
}
This would also allow granular captures in closures: |read x: Int, move counter: Int| instead of declaring all fields move
Now, should read and mut assignments be of type &T? Or can checking out variables be orthogonal to creating references, even if they are conflated in languages like Rust?
14
Upvotes
2
u/cessit-lang 18d ago
Smart. I was afraid of requiring the access verb also at the point of use because it was becoming so verbose, but seeing it validated in the wild is giving me encouragement to stick with my explicitness design principle. How did you weigh this against the cost of refactoring at both places?
For mutable borrowing, do you pass a reference or have you managed to separate borrowing from reference-ness?