3 ms·
I've written about 10 thousand lines of Rust at this point and hope to write much more. After "suspending frustration" and internalizing the borrow checker and
by cjcole 12y ago
I've written about 10 thousand lines of Rust at this point and hope to write much more. After "suspending frustration" and internalizing the borrow checker and the idioms it just works for me now.
That said, I still get minor jets of frustration when this works:
let y = a.b.c;
But this does not:
let x = a.b;
let y = x.c;
And this works:
let x = foo.bar();
let y = foo.baz(x);
But this does not:
let y = foo.baz(foo.bar());
due to scoping and borrow checker rules. Papercuts, yes, but annoying nonetheless.
That said, Rust (effortlessly) caught what could have been a very dangerous bug for me last night (I'm using a Rust wrapper around Lua): when you call "tostring" in Lua it returns you a reference to a string on the Lua stack. If you then pop the Lua stack the reference becomes invalid. If you then use the reference to the string, well... (This is akin to iterator invalidation.)
Rust's borrow checker flagged the error and its error reporting made the problem obvious. This will make up for a very large number of papercuts.
- sanderjd 12y agoYou've captured one of my somewhat late realizations about rust – some seemingly-simple refactors change semantics in ways you might not immediately expect, coming from most other languages. In addition to the ones you mentioned, I'm sometimes frustrated when trying to extract methods, sometimes because of moves and sometimes because of needing to write out a complex return value where the type was previously inferred. But I have personally found it to be true that (as with any other language) you get a gut sense for the semantics of the language and stop fighting against them over time.
- cjcole 12y agoThe core problem is that the set of safe programs is considerably larger than the set of programs which pass a tractable, maintainable, and (potentially) provably safe compiler (including borrow and type checkers). You want to enlarge the latter set, since that lessens programmer frustration and increases expressiveness, but in the context of a non-garbage-collected language that often requires adding complexity to the type and borrow checkers which may in turn end up introducing bugs. A discussion of various run-ins with the borrow checker and some details of attempts to reduce the friction: https://github.com/rust-lang/rust/issues/6393 https://github.com/rust-lang/rust/issues/6393 'Both @pcwalton and @zwarich spent some time trying to actually implement this work (with a possible RFC coming hand-in-hand). They ran into some unexpected complexity that means it would take much more work than hoped. I think everyone agrees with you that these limitations are important and can impact the first impression of the language, but it's hard to balance that against backwards-incompatible changes that are already scheduled.' [added on edit:] In particular, here is a very nice statement of the issue(s): https://github.com/rust-lang/rust/issues/6393#issuecomment-24307095 https://github.com/rust-lang/rust/issues/6393#issuecomment-2... nikomatsakis: 'I'd also like to have more progress on a soundness proof before we go about extending the system.' And here again is the tension between complexity in the compiler and the coverage of the space of safe programs.