5 ms·
I would urge particularly c++ people to try rust. It's not really a huge jump thinking about borrowing, especially as you're already thinking about move/copy se
by lordnacho 4y ago
I would urge particularly c++ people to try rust. It's not really a huge jump thinking about borrowing, especially as you're already thinking about move/copy semantics in modern c++.
I wrote a trading system in rust recently, it was a breeze. I was never stuck with strange issues or crashes, everything that went wrong was reasonably clear. With c++, once you get a segfault you never really know if you've actually fixed it or just gotten lucky. Mysterious crashes are also a huge timesink, because you tend to have to stop what you're doing on look at what happened, and then when you fix it it's quite possible you're just relocating the problem. Even if you avoid those issues, you will have to periodically run through your code with some valgrind or similar tools, and then you have the awkward "should I do something about this warning".
I don't think this dive was terribly deep though. It was good to look at the IR representations, but what often trips people up isn't that textbook use-after-move example. I'm sure there's a menagerie of strange "why does the borrow checker complain" examples where it's a little less obvious why the lifetimes are wrong. In particular, when you have to annotate the lifetime yourself, things get weird and it's not always obvious what to do.
- bowsamic 4y ago> especially as you're already thinking about move/copy semantics in modern c++. The thing is, you can get away with a reasonable sloppy and half-hearted knowledge of those things in modern C++, unlike in Rust, which is of course strict
- pornel 4y agoIt does remind me of dynamic typing vs static typing difference, except C++ is "dynamically owned", and Rust is "statically owned". With the dynamism you have the freedom to make whatever ad-hoc memory management constructs you like without formally explaining them to the compiler, but also you don't get compile-time guarantees that they are correct.
- blub 4y ago“With c++, once you get a segfault you never really know if you've actually fixed it or just gotten lucky” This only applies if one is randomly changing things instead of actually fixing the problem. :-)
- cyber_kinetist 4y agoI've tried Rust before. in the end I concluded that I don't really need it over C++ for the following reasons: - I tend to store references to other objects using indices instead of pointers/references anyway, so the borrow checker isn't really that important for me. Memory errors that comes from indexing can be caught with runtime assertions, or if you can't use assertions because of performance constraints you can still use sanitizers to debug these issues. (You're probably going to run sanitizers even in Rust anyway if you are using unchecked array indexing...) Further use-after-free errors that come up with reusing indices in an object pool can be caught at runtime using the generational index trick. (See https://kyren.github.io/2018/09/14/rustconf-talk.html https://kyren.github.io/2018/09/14/rustconf-talk.html for the gist of what I'm talking about. The presenter listed this as a reason why Rust is good because the compiler nudges you circumvent the borrow checker to design better code, but for me this was actually a reason why Rust doesn't actually help that much at all: I don't need the guidance of the borrow checker to have this decision in the first place! She's actually giving a reason for why the borrow checker is useless!) - Also, Rust's compile-time facilities are still not as powerful as C++'s. For example in Rust you can't still do operations with integers in generics in compile time, you need to wait that until the full version of const generics. (This is important if you want to make a convenient math/linear algebra library) SFINAE is dirty but still more powerful than what you could do in Rust with trait bounds, template specialization is also absent in Rust. C++ also has 'constexpr if' which makes type-level programming much simpler than what you need to wrangle in Rust. At least Rust has hygienic macros, but to be honest it's a bit cumbersome to use and seems to be designed as an afterthought. (Overall C++'s templates are 'dirtier' than Rust's traits but are far more powerful. But I really like how languages like Zig and Jai approach compile-time programming though... these are the languages I'm more excited about than Rust or C++) - Unsafe Rust is still much limited than what you could do in C/C++, but still really hard to write. Even when I have a rough picture about how I would exactly implement a system in low level terms, Rust's complicated semantics around safe/unsafe severely distracts me from actually implementing some actual shit. (Arguably this is the same for modern C++ where you need to know all these weird move/copy semantics to implement even simple generic containers like vector<T>, but the best solution for that is to use simple POD structs as much as possible and suddenly your worries tend to disappear.) - This is probably a bit too unfair, but I would actually like to use some battle-tested C/C++ libraries right away rather than wait for someone to do the gnarly FFI binding work or even "reimplement in Rust(TM)". Still, Rust has some nice features like ADTs, pattern matching, and syntax sugar for Error types, so maybe the tradeoffs can be worth it if some of these pain points are solved. Around the time when the full version of const generics is finished I might start exploring Rust again.
- saurik 4y ago> With c++, once you get a segfault you never really know if you've actually fixed it or just gotten lucky. FWIW, while I totally agree with the argument that I would prefer to be able to prove my code doesn't have this kind of bug, this statement goes too far: if you don't know what was wrong with your code before and you merely whacked at it randomly until it stopped crashing your work isn't done... you should know exactly why your code crashed before and know for sure that your new code doesn't exhibit that same issue--as well as think about how to avoid ever making the same mistake again, potentially doing drills with the concept so it becomes a bit more intuitive or adding new compile time lint behaviors--before you move on to your next task (and this is how you should be treating bugs of all forms, not merely segment faults). Regardless, my issues--as a long-time C++ developer--are that I am pretty firmly addicted to all of the compile time programming benefits of C++ (which sometimes let me pull of safety tricks that are more indicative of a dependently-typed language) that other people have already mentioned... but I am also pretty addicted to unchecked exceptions, and see absolutely no reason why Rust decided to re-tread error handling mistakes I've seen in prior programming languages (awkwardly including Java, which has checked exceptions, and feels more similar in spirit to Rust than C++). (That said, I do appreciate that the syntax sugar for papering over this has gotten better with time, but I still think the people who don't appreciate that exception-safe code is actually important to write in all situations and if you can't do it your code probably can't be correct even in the case of a language without exceptions are missing something important about the nature of errors.)