This was my impression as well when I tried Rust - always fighting the compiler. None of this happens with D. You just code away and keep being productive without the annoyances of C++. In fact C++11 and 17 are less and less annoying.
Fighting which stops eventually. I program Rust for nearly a year now and I found that there is a point where it gets quite smooth. The many mental guarantees that the code gives you can help you a lot to stop worrying about a whole class of things. I realized just how much this is the case when I wrote something in Python again and separation of which code affects what and which code is doomed to fail from the start became much harder.
Rust initially has been a lot about fighting the borrow checker, but once you get the hang of it it happens quite often that you write pages of a complex functionality including tests – you hit build and it just works.
I am certain that Rust prevents entire classes of problems I filed bug reports for, even with extremely experienced developers. I understand that the nagging voice of the compiler or cargo clippy is not just for everyone, tho.
I believe you’ve not been on the receiving end of a 17 page compiler error while trying to compile a template heavy app, because you forgot to put an &.
The important part is to realize _why_ you’re fighting the compiler as it’s trying to make _you_ write better code and improve.
If you find non issues being reported by the compiler please report it and make it better for all of us too!
> as it’s trying to make _you_ write better code and improve.
It’s not necessarily an improvement. When an algorithm processes complex data structures organized in graph or tree, no amount of better code allows to easily implement that in Rust. It’s either slow, or unsafe and hard to implement, or both.
Even without trees, consider a simple LRU cache structure. Trivial to implement in most languages by combining linked list with hash map. Rust implementation is more than 1000 lines of code, many of them are unsafe: https://docs.rs/linked-hash-map/0.4.2/src/linked_hash_map/li...
I never wrote production code in Rust. But based on my limited experience, the language is fine for projects that have few data structures, or they’re simple so you can stick to library containers, and a lot of code processing them. For many practical problems it’s quite the opposite.
> Even without trees, consider a simple LRU cache structure. Trivial to implement in most languages by combining linked list with hash map. Rust implementation is more than 1000 lines of code, many of them are unsafe: ...
in this context, criticizing using unsafe in rust and comparing that to C++ is comparing apples to oranges. GC languages aren't even worth mentioning here.
> It’s not necessarily an improvement. When an algorithm processes complex data structures organized in graph or tree, no amount of better code allows to easily implement that in Rust. It’s either slow, or unsafe and hard to implement, or both.
here's the thing: all of the above are true in other languages, C/C++ included, it's just that no compiler besides rust will warn you that recursive data structures are hard - it doesn't matter if implementing them is easy, proving they're implemented correctly never is. rust tries to help you prove you did the right thing and it needs assurances (unsafe) where it just can't do that. C++ is all unsafe.
> criticizing using unsafe in rust and comparing that to C++
In that comment I was mostly criticizing the amount of code. That code doesn’t need to be written in C++. std::list has stable iterators so you can put list iterators to the hash map. This way LRU structure becomes a trivially simple wrapper over std::list and std::unordered_map containers.
Note how Rust developers implemented custom linked list on top of raw pointers, doing manual memory management with Box::into_raw(Box::new(Node::new(k, v)))
C++ implementation doesn’t need a single new/delete, hence much safer than unsafe rust. LRU cache is simple, not too hard to implement correctly in C++ just because it’s very few lines of code.
> it's just that no compiler besides rust will warn you that recursive data structures are hard
In GC languages like C# or Java it’s both easy and safe.
In C++ they can be challenging to implement correctly, but because it’s all unsafe, I get huge amount of help from all levels of the stack. OS debugger, C runtime, C++ standard library, compilers, they all evolved for decades trying to improve life of developers like me writing unsafe programs which use raw pointers. You can implement a recursive data structure without a single new/delete, relying on standard collections for memory management. It doesn’t guarantee pointer safety just like unsafe Rust doesn’t, but at least no need to worry about memory leaks.
Let's be clear: Rust is still far away from formal verification; the borrow checker won't save you from logical errors.
Second, data structures like graphs, trees, hashmaps are well understood and have a lot of algorithms built on top of them. Algorithms with a lot of research behind them, and complexity analysis. While complexity analysis doesn't always equal performance, if I can't use these universal tools in your language, I'll probably think of it as a toy language which stops me from getting stuff done, which is still what most of us are paid for.
> Let's be clear: Rust is still far away from formal verification; the borrow checker won't save you from logical errors.
completely agree.
> Second, data structures like graphs, trees, hashmaps are well understood and have a lot of algorithms built on top of them.
well understood, yes, by authors of textbooks and papers. your average programmer may have understood them once, before he made it to the enterprise and started passing buckets of bits between http endpoints for a living.
> Algorithms with a lot of research behind them, and complexity analysis. While complexity analysis doesn't always equal performance, if I can't use these universal tools in your language, I'll probably think of it as a toy language which stops me from getting stuff done, which is still what most of us are paid for.
you can write a recursive data structure in Rust in the same way you'd write one in C++ - use unsafe pointers, even the asterisk is the same. nothing is stopping anyone from doing that, in fact there are lots of examples on crates.io and in the stdlib.
Your argument doesn’t make much sense. You can use unsafe and raw pointer to do EVERYTHING you can do in C/C++ and it will be just as safe as you write it in C/C+. And then, you can (ab)use the type system to make sure you or your team cannot use it in the wrong way.
> and it will be just as safe as you write it in C
C++ standard library containers have guarantees about iterators and pointers invalidation, e.g. std::list never invalidates any of these, unordered_map invalidates iterators when rehashed and never invalidates pointers to either keys or values. This allows building unsafe data structures on top of standard collections, and then compose custom unsafe data structures on top of each other.
This makes C++ both safer (at least from memory leaks) and easier to use compared to unsafe rust.
why would i use rust in the first place if i was disabling the borrow checker? isn't that the main selling point?
because of the ecosystem? because it's easier to hire rust programmers than C/C++ programmers, or get more open source contributions from rust vs C/C++? unlikely with a learning curve or community like that.
The idea is good, MS did same in C# since the first version in 2002. Allows to do pointer arithmetic when you really need to, for performance or native interop.
What I don’t like about Rust is they use unsafe to workaround language limitations.
In C# I have only used unsafe code couple times over the course of 20 years. The standard library doesn’t use unsafe code either, at least in modern .NET all these collections are 100% safe code. The main, safe subset of the language is good enough for the majority of practical applications.
In Rust there’s tons of unsafe code in standard library, substantial amount of unsafe code in third-party libraries, and if your software is complex enough, your own code will likely contain usafe as well. This causes safety issues: https://medium.com/@shnatsel/how-rusts-standard-library-was-...
One of the reasons the standard library has a lot of unsafe is that the standard library is small, but one of the criteria for being in the standard library is “uses a lot of unsafe.” We’d rather these things get massive visibility.
In all my years with Rust, the only unsafe I’ve needed in any of my applications is when doing FFI, and my toy OS. YMMV.
Being able to use more D would be nice! But the binding issues remain the same there. There recently was talk about having the D compiler emit C++ headers for exports from D modules automatically. This would be an instant killer feature for me.
Yes, dpp has issues with C++ constructs according to its readme unless that changed recently. I am talking about the inverse: have dmd generate a C++ header automatically for extern(C++) declarations during compilation. This was discussed quite recently.