4 ms·
I have been playing with Rust for a few weeks now, so I can give a few reasons not to use it. What I will write may sound overly negative, but keep in mind that
by wuch 11y ago
I have been playing with Rust for a few weeks now, so I can give a few reasons
not to use it. What I will write may sound overly negative, but keep in mind
that those are only reasons not to use it, in general I found a lot to like in
Rust.
Unsurprisingly most of issues described below, boil down to Rust not being
mature yet, and are perfectly fixable. However, fixing some of those will break
backward compatibility one way or other and require effort that would be
unnecessary otherwise.
Language is underspecified. In what order are subexpression evaluated in Rust?
Unspecified yet, in fact it is even worse than that, it differs between borrow
checkers (which I think uses the most useful one given Rust syntax: right to
left behaviour), while code generation assumes left to right order.
https://github.com/rust-lang/rust/issues/28160 https://github.com/rust-lang/rust/issues/28160
What can you do with pointers in unsafe parts of code so that everything is
still well-defined. There does not seem to be real answer to this question yet:
https://github.com/rust-lang/rfcs/issues/1447 https://github.com/rust-lang/rfcs/issues/1447
What does Rust guarantee with respect to lifetimes? In fact it guarantees much
less than what would you expect. Take for example a drain method of a Vec.
Drain gives you an iterator that moves elements out of a Vec. Naive
implementation would leave Vec in a inconsistent state while drain iterator is
still alive (because some of elements are already moved from), but restore Vec
to a valid state in destructor of drain iterator. It appears to work because no
one can touch Vec while drain iterators still holds mutable reference to it.
Except it wouldn't work, because Rust does not guarantee that drain destructor
will be executed, in fact in perfectly safe code it may not be executed at all.
Surprisingly a borrow of a mutable reference may outlive the lifetime of a referent.
At least it seems that Rust guarantees that those references would be
inaccessible.
https://internals.rust-lang.org/t/are-memory-leaks-considered-to-violate-memory-safety/1674/2 https://internals.rust-lang.org/t/are-memory-leaks-considere...
There are quite a few language issues like this, and in general I found it very
hard to find what exactly Rust semantics is.
Rust sends mixed signals about panic. On one hand it try to tells you that code
that panics is probably badly broken, and may have left data structures in an
inconsistent state, so you should not even try to access them. And Rust tries
to ensure this to some degree by putting roadblocks on your way if you think
otherwise (see Mutex poisoning, and strange things like AssertRecoverSafe you
have to use when recovering from panics). Except in reality, all your
desctructors already do access all those data structures. It seems that all
those roadblocks are quite pointless.
Running out of memory aborts program. This is I think quite a bad decision (it
seems that this may be a temporary one) for a language that have exceptions in
form of panic. Not many programs need to handle out of memory situations, but
handling those in programming language with exceptions and RAII is quite easy,
and mostly boils down to: don't perform dynamic memory allocation in
destructors. This is a step backwards from C++.
Bugs, bugs and more bugs. Rust not calling your desctructor for variables in
the same scope after panic, still there after more than a year:
https://github.com/rust-lang/rust/issues/14875 https://github.com/rust-lang/rust/issues/14875
Borrow checker is interesting, certainly prevents you from writing buggy code,
but also prevents you from writing code which is perfectly fine. In certainly
does not play nice with ideas which are very common in C++ world, any STL
algorithm + container would be a good example. I am still not sure if it is
worth the effort, it seems to prevent problems that I don't commit in C++
anyway.
Immature state of ecosystem, libraries, documentation, ... .
In general you probably will not be as productive in Rust now as you would be
in other languages. If you are interested in developing those libraries that
are currently lacking, having some impact in how Rust language may look in a
future, then Rust community is certainly great. But a lot of people have
different priorities.
- pcwalton 11y ago> However, fixing some of those will break backward compatibility one way or other and require effort that would be unnecessary otherwise. We aren't changing anything you're talking about, except for bugs. > In what order are subexpression evaluated in Rust? Unspecified yet, in fact it is even worse than that, it differs between borrow checkers (which I think uses the most useful one given Rust syntax: right to left behaviour), while code generation assumes left to right order. https://github.com/rust-lang/rust/issues/28160 https://github.com/rust-lang/rust/issues/28160 That is not the standard question of right-to-left vs. left-to-right argument order. That is perfectly well defined: left to right. Rather, it's a very subtle question involving code nobody would write in practice. > Except it wouldn't work, because Rust does not guarantee that drain destructor will be executed, in fact in perfectly safe code it may not be executed at all. This is never a problem in real world code. The leakpocalypse affects nothing in the real world and was a lot of debate over what amounted to a very minor hole. C++ has no guarantees about destructors being executed at all, and frequently due to memory management errors they aren't. Rust guarantees that they'll be executed unless you're leaking. > Bugs, bugs and more bugs. Rust not calling your desctructor for variables in the same scope after panic, still there after more than a year: https://github.com/rust-lang/rust/issues/14875 https://github.com/rust-lang/rust/issues/14875 C compilers have miscompilations too, with the same frequency. I never hit these in practice. > I am still not sure if it is worth the effort, it seems to prevent problems that I don't commit in C++ anyway. Yes, you do make those errors. Empirically. All large C++ projects I have ever seen have memory management errors, unless they're doing hugely expensive verification. I have not yet seen an exception. > Running out of memory aborts program. This is I think quite a bad decision (it seems that this may be a temporary one) for a language that have exceptions in form of panic. It's not a temporary one. Most programs don't need to handle out-of-memory conditions, and having the language do this is not a step back from C++. For programs that do, you can use libcore (recently stabilized!) and handle this yourself. You're looking through the issue tracker, pulling out random bugs, and overstating their impact. Someone could do the same to any C++ compiler; LLVM has horrible-looking miscompilations all the time, and it's still production ready. Of the reasons not to use Rust, miscompilations (which is the vast majority of what you're talking about) aren't anywhere near the top of the list; they occur more or less with the same frequency they occur in C++. You can't complain that the borrow checker doesn't solve memory management issues you hit in C++ and then simultaneously criticize Rust by citing a whole bunch of issues that occur with much less frequency than those memory management issues.