7 ms·
I often feel the same, and there is certainly a bit of learning curve, but in my experience, all the time you spend battling the compiler in Rust is time saved
by larschdk 5y ago
I often feel the same, and there is certainly a bit of learning curve, but in my experience, all the time you spend battling the compiler in Rust is time saved from debugging in C++, several times over. I'm repeatedly surprised by how my code just works when it finally compiles. It's like the compiler is telling you, "you just made a bug".
- skohan 5y agoJust to give an alternate viewpoint, I'm currently writing most of my code in Rust, and while I am generally a fan of the language, and a huge fan of the tooling and community, I think Rust often gets a pass on complexity because it's mostly compared against C++ which is itself a monstrosity. There are many, many other languages to which Rust seems insanely complex and difficult to program in by comparison. I think that often gets blamed on accommodating the borrow checker, and Rust's low-level nature, but I think a lot of it is avoidable.
- steveklabnik 5y agoI'm curious, not saying you're right or wrong: what bits do you think are avoidable? Personally, I agree that Rust is complex, but almost all of that complexity is inherent to the kinds of tradeoffs Rust makes. With different tradeoffs, I can certainly imagine a much simpler language, but it's less clear to me what stuff could be significantly simplified without doing so. However, I am extremely biased!
- skohan 5y agoMy go-to example would be the module system: 1. 90% of the time, rust module layouts are basically a copy of the file-system heirarchy, so why do I have to type this? This system would be much more approachable if it gave the file-system hierarchy as the default module layout, and let you override it explicitly. The argument I have heard against this is that some people like to comment out module declarations during debugging. I don't find this compelling, because I don't see why you couldn't have an explicit way to ignore a module instead. This is just one of many cases where Rust seems to prioritize the edge case at the expense of the common case. 2. On top of requiring a lot of boilerplate the module system is quite esoteric. I've had to learn it twice: a few years ago I was dabbling in Rust, and I remember having to struggle a bit to understand how to add a second file to my project, and then about a year ago when I was getting back into rust I found it unintuitive a second time. I challenge you to find someone who is unfamiliar with the module system, and see how long it takes them, using only the documentation, to figure out where they have to put the `mod` declarations to add nested submodules to their project to make it compile. Maybe I am unreasonably thick, but I don't think it's my problem since I've worked with a lot of languages, and never had this much trouble. 3. This esoteric system isn't even deterministic. Imagine I have the line `mod foo` in my `lib.rs`. Where can I go to find the source for that? Well, it depends. It could be in `src/foo.rs`, or it could be in `src/foo/mod.rs`. And let's say I'm using external crate: `use some_crate`. Which import does that correspond to? It could be: `some_crate`, or it could be `some-crate` in my `Cargo.toml`. You just have to kind of know all of these implicit behaviors of the compiler to know what's going on. So this is just one feature, but IMO it's just one example of a case where Rust puts very little emphasis on the UX and understandability of the language.
- steveklabnik 5y agoCool thanks! This is a great example of my mental bias, actually: I don't tend to think of the module system as a "language feature" even though it clearly is! There are some good reasons and interesting arguments around all this, but given that I was just curious about your opinion, I won't bore you with all that :) Thanks!
- skohan 5y agoNo worries, happy to share!
- iudqnolq 5y agoI definitely think you're right that the module system is complicated, even the new module system. I would like to make one nit though: it's definitely deterministic. Deterministic just means it can be predicted, not that you specifically can predict it. If the module system was non-deterministic that would be a much bigger issue
- skohan 5y agoOk fair enough, that is true. I guess it would be more accurate to say that a module declaration is ambiguous with respect to the file-system location of the code it's referring to.
- skoodge 5y agoI'll chime in and say that for me at least, the module system was a hurdle at the start and coincidentally the only part of the language where the explanation in The Book (which is excellent, so thank you, btw!) did not click for me. I think it's debatable whether the module system really is complex or just different from what newcomers are used to (and by now I've grown pretty accustomed to it). But in contrast to most other language features, where it was clear what I was getting in return for the steep learning curve, the module system seemed overly complicated at the time for no real benefit. Not a big issue by any means and I would choose Rust with its module system over the alternatives most days of the week, but it is one tradeoff that to me at least seemed orthogonal to the other borrowing-related complexities. (What is more worrying to me nowadays is the whole async story. I do hope that some of it will get better once certain features land and it is certainly an area where some additional complexity is unavoidable, but it is the only part of Rust that I dread touching despite heavily using async in a moderately sized personal project due to the need for WASM + IndexedDB, simply because lifetime issues become much more tricky once async and either traits, recursion or closures are involved. By now I am consciously trying to limit any async parts of the program to a simple and stupid "Rust-light" style without any "fancy" features such as traits or closures, which does not feel like a proper solution. So yeah, in general I agree with you: Rust is certainly complex, but for the most part not unnecessarily so.)
- estebank 5y agoYou might be interested in taking a look at and potentially participating in the "Async Vision Document"[1] which is an exercise the team is going through to collect feedback about the current state of the ecosystem and what the pain points are, as well as a way to lay doing what the desired future state of async Rust should be[2]. The process is happening, as you would expect, in the open and there's still time to influence it[3] if your concerns aren't yet addressed or even mentioned[4]. [1]: https://rust-lang.github.io/wg-async-foundations/vision.html https://rust-lang.github.io/wg-async-foundations/vision.html [2]: https://blog.rust-lang.org/2021/03/18/async-vision-doc.html https://blog.rust-lang.org/2021/03/18/async-vision-doc.html [3]: https://github.com/rust-lang/wg-async-foundations/pulls https://github.com/rust-lang/wg-async-foundations/pulls [4]: https://github.com/rust-lang/wg-async-foundations/issues https://github.com/rust-lang/wg-async-foundations/issues
- ncmncm 5y agoIf you ever find yourself spending time "debugging in C++", you are Doing It Wrong. Coding modern C++ right is the same, that way, as coding Rust: when it compiles, it works. (In general, if you find yourself inventing falsehoods about other languages to promote Rust, you are Doing That Wrong, too.) I have personally spent more time, summed over the past decade, preparing bug reports against Gcc than in debugging C++ memory-usage faults. But C++ compiles faster. Coding Rust is fun in much the way that Forth is: it is a charge to figure out a way to achieve a thing; you know it will ultimately be possible, and when you find the way, it is an ego boost. You could say, "Rust is the Second Programming Religion", and who could ever honestly disagree? (But watch extremists downvote this to oblivion anyway.)
- skohan 5y ago> it is a charge to figure out a way to achieve a thing; you know it will ultimately be possible, and when you find the way, it is an ego boost. This is actually something I agree with, even as a fan of Rust. Sometimes I wonder to what extent the appeal of Rust is based in the fact that you get to feel like a CS undergrad again, climbing mountains to make code compile and run
- linkdd 5y agoIt was my understanding that the memory model of Rust is inherently different than C++'s. Genuine noob question: can you really compare Rust's borrow checker and lifetime management to the smart pointers in C++?
- steveklabnik 5y agoYou can compare them, but the comparison won't show that they're equal :p C++'s smart pointers have direct analogues in Rust, though there are some differences. (unique_ptr<T> and Box<T>, shared_ptr<T> and Rc<T>/Arc<T>) The borrow checker is something else completely. The closest analogue in C++ is the https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines, which offer some similar kinds of checks to Rust, but don't attempt to go nearly as far as Rust does.
- 5y ago
- torrent 5y agoAfter your battle with the compiler is over and it compiles it does not mean your program is correct! If you now what you you have no issues with C++. It's not the language. It's the design, approach and attitude