3 ms·
A shallow learning curve and cute compiler messages are the least of your problems when doing C++-caliber software. The 'small, easy language for ignorant deve
by otabdeveloper1 8y ago
A shallow learning curve and cute compiler messages are the least of your problems when doing C++-caliber software.
The 'small, easy language for ignorant developers' niche certainly exists, but it's already taken by Go.
Rust currently provides no benefit over (modern) C++ for the problems where using Rust or C++ makes sense. (Though perhaps Rust will make it easier for layman developers to learn Rust and then transition to C++.)
- andy_ppp 8y agoInteresting! I don’t know how modern C++ deals with multi threading and shared memory etc.? Care to fill us in on the state of the art and how it’s as good as rust?
- otabdeveloper1 8y agoState of the art is pthreads and mutexes. The C++ and Rust wrappers for them are roughly equivalent. Rust has some nice features for handling ownership semantics, but they are not significantly better than those in C++. Meanwhile, Rust still lacks a normal exception handling story. Exception handling is absolutely necessary in 2018 for building real software systems. (And even though Rust claims that errors are nicely dichotomized into "recoverable" and "not recoverable" camps, this is simply not true in the real world. There are obvious counterexamples that don't fit into this dichotomy.)
- setr 8y agoHaven't spent that much time with rust, but so far Result<> has sufficed for all my exception-needs; it's not clear to me what the practical difference is between exceptions and result<>, that would be relevant to implementing real software systems? As I understand it, the primary usage of both is to report, and handle, errors. Rust splits it as panic! and Result<>, where panic! is naturally left for logic errors (ie states the program should never reach, regardless of circumstance; maintaining invariants), and Result<> is for everything else. Exceptions do the same, but you can catch the broken-invariant case as well? I'm not sure how often you want to recover from such a state though. Another aspect is retrieving the stack-trace, which iirc doesn’t exist in a normal result-type, but error-chain! magically handles it for my case (never looked into how, or at what cost) Otherwise, the other major difference is that rust enforces that you explicitly handle all result types, making it part of the API contract, while most languages, with unchecked exceptions, leave it as a new runtime error to be found after updating your libraries. Java gives you checked exceptions, but in a much more syntax-unpleasant fashion (but thats always the case with java). As far as I'm aware, Result<> seems to me a much cleaner solution than exceptions for the same use-case. A bit of concern for API updating, since the errors are part of the API so its more difficult, but at the same time, I'd rather update the library and fix the codebase, than update and wonder if a new Exception exists (or perhaps, always existed? Is there any way to find out the list of possible exceptions in C++, without reading the function, and all the code it depends on?). The primary unpleasantness is that a single use of Result<> infects the entire callgraph until its handled, but thats true with exceptions as well. I'm not too happy about async/await for the same reason Of course, part of the reason I'm interested in using rust as my hobby-language is because I'm absolutely sick of runtime errors and writing worthless tests in python, so maybe there's an appeal thats missing for me
- otabdeveloper1 8y ago> I'm not sure how often you want to recover from such a state though. Pretty much always in real systems software. Imagine a multithreaded server that handles HTTP requests. A catastrophic invariant failure when handling one requests shouldn't bring down the whole server. Or imagine an application that calls into a money transaction routine. (This routine can itself call other routines, and so on for 12 stack frames deep.) A catastrophic failure in sending money shouldn't bring down the whole app, it should show a clean "money transfer failed, please try again" message.
- qwertycrackers 8y agoThat's why you would return a Result from all those and handle any failures that way. The Result type is meant to be used any time an operation could fail.
- setr 8y agoWhen I'm talking about invariants, I mean something much more fundamental than a web-request failing. It's not a necessarily invalid state (and I'm not sure ever should be for any well-behaved program). It would be invalid if you've explicitly decided not to handle the scenario, but at least in Rust (and assuming the function properly returns Result<>), you can't forget to not handle it. Essentially where you'd have asserts() in C. eg Your in-place sort function is meant to maintain a sorted list for all elements traversed so far: you add a panic check to guarantee this. It fails; the invariant is broken, and there's no recovering from such a state (your sort is not sorting! you're going to add a handler for this..?). A web-request failing is a simple, normal, expected failure (hence the Result<> type). Adding 1+1 and getting 3 is a broken invariant, and there's no coming back from it. Again, you can (probably) catch it in Java since it throws exceptions on anything and everything... but why would you want to? If you take its to its conclusion, you're not trusting any aspect of the language anymore: you'll have to check every bit of code for arbitrary outcomes. It seems to me similar to javascript allowing you to basically pass in anything to everything and get ...some... output, but its an extremely bug-prone methodology. panic! is, afaik, intended for those situations where it should bring down the whole application (before you start adding $3 to person A, but subtracting $2 from person B); primarily to catch programmer errors, not execution errors. Errors that can be recovered from are Result<>, and the Result<> type forces you to handle all possible outcomes (which the caller might decide is a panic!). A failed web-request is most certainly a Result<> in this model, not a panic!.
- the_duke 8y agoI doesen't look like you have spent any time investigating Rust at all.
- Rusky 8y agoI... what? Rust is hardly targeting "small, easy language for ignorant developers," and putting it in that camp because it has nice error messages is unreasonable. I'm even more perplexed by "Rust currently provides no benefit over (modern) C++." * Rust's "pthreads and mutexes" wrappers prevent data races at compile time, and there's Rayon to compete with things like OpenMP. * Rust's moves are destructive, guaranteed nothrow, and also checked at compile time. * Rust's borrow checker is light years ahead of C++'s. * Rust's type system lends itself to far simpler generic code, with trait-based generics and sum types instead of concepts and std::variant. * Rust's iterators are much better than C++'s, to the point that Ranges is one of the most highly-anticipated additions to C++. All of these are things C++ is actively trying to improve, so clearly at least the committee agrees they're worthwhile features.