Before 1.0, I wrote a linear types RFC, so I’m personally annoyed by how influential this article seems to have been. The costs are, as Aria admits, not as bad as they had thought when they started the article (rewriting APIs would certainly be highly annoying. I’m reasonably certain it could also be significantly automated, but the ecosystem churn could be pretty horrid. I also no longer think linear types can be reconciled with panic=unwind, but I always strongly preferred panic=abort anyway), and the benefits of linear types seem to have gotten stronger over time (they could solve perhaps the biggest foot-gun in async Rust, preventing implicit cancellation when some operations are expected to run to completion). A code pattern shown in the article (quoting)
let mut token = None;
while cond1 {
if cond2 {
token = Some(step1()); // ERROR 1: assignment to already initialized must-use value
}
if cond3 {
step2(token.take().unwrap());
}
}
// ERROR 2: must-use value must be used
isn’t something you’d want to encourage if you’re using linear types, in the same way that using bare pointers – even when provably safe! – isn’t something the Rust language encourages. (Rust can be comfortable ruling out some classes of correct programs in order to encourage more compiler-verifiable correctness.) Being able to array[i] = val; wouldn’t work, but you wouldn’t want it to work. The point of linear types is to force users to avoid letting values fall on the floor. old_val = std::mem::replace(&mut array[i], val); verifies that they’ve done so. The pain of linear types is the benefit.
I continue to think Rust would have been better off with linear types, but I never had the time I needed when I needed to push the argument forward, and now I feel like the ship has sailed. Oh well.
Before 1.0, I wrote a linear types RFC, so I’m personally annoyed by how influential this article seems to have been. The costs are, as Aria admits, not as bad as they had thought when they started the article (rewriting APIs would certainly be highly annoying. I’m reasonably certain it could also be significantly automated, but the ecosystem churn could be pretty horrid. I also no longer think linear types can be reconciled with
panic=unwind, but I always strongly preferredpanic=abortanyway), and the benefits of linear types seem to have gotten stronger over time (they could solve perhaps the biggest foot-gun in async Rust, preventing implicit cancellation when some operations are expected to run to completion). A code pattern shown in the article (quoting)isn’t something you’d want to encourage if you’re using linear types, in the same way that using bare pointers – even when provably safe! – isn’t something the Rust language encourages. (Rust can be comfortable ruling out some classes of correct programs in order to encourage more compiler-verifiable correctness.) Being able to
array[i] = val;wouldn’t work, but you wouldn’t want it to work. The point of linear types is to force users to avoid letting values fall on the floor.old_val = std::mem::replace(&mut array[i], val);verifies that they’ve done so. The pain of linear types is the benefit.I continue to think Rust would have been better off with linear types, but I never had the time I needed when I needed to push the argument forward, and now I feel like the ship has sailed. Oh well.