Therefore, use Rust if you really have to. Otherwise, tools like automated garbage collection are a much better way to reduce the likelihood of bugs.
Therefore, use Rust if you really have to. Otherwise, tools like automated garbage collection are a much better way to reduce the likelihood of bugs.
I've seen people learn Rust as their first programming language, and it fills me with joy that the next generation of programmers won't have to build up this vault of apocryphal knowledge I've had to over the years. Or, at least, not the same one. And hopefully not as large.
I've also found Rust to be a very pleasant application development language. As a former NodeJS developer, I've been able to replace Express with Warp and Electron and React with Iced. It's not ready for all things, but it's ready for a heck of a lot. And the question of "what's possible" has broadened so much due to work by the community in even just the past year, I really think the majority of all other applications, including web frontend (cargo web), servers, desktop apps (iced), and mobile apps (cargo mobile), can be reasonably implemented in most part entirely in Rust within only a few years.
That's not really true: Rust's borrowing and ownership apply to most kinds of in-program resource ownership and aliasing, not just memory.
> The resulting code then creates an increased cognitive load which can make other bugs more likely.
I'm not saying you're wrong, but I'd like to see any evidence for this. Personally, I'd expect the opposite to be true: knowing whether any given object is non-exclusively borrowed, exclusively borrowed, or owned at any point in the program sounds like very useful documentation for people reading the code.
I'm not in a position to claim that this theory is actually true, and I won't take a stance which is "better", but personally the former is much more appealing to me, for purely aesthetic reasons.
Also, much of the tooling I used to add to projects in other languages is either built-in and commonly used (test, fmt), or easily added to cargo (edit, bench, web, mobile).
Enums in C are just ints with names. They're error prone and not type checked. You can always use 0 instead of a name and it will work. You can use TLSv2 instead of ExterminateHumans and it will also work.
> What I mean by it is significant "programming in type language" as opposed to "in code language".
I honestly don't understand what you mean by this.
Yes, they are integers. You can do arithmetic with them, you can use them as bitmasks, or use sentinels instead, like -1. I like that.
Them: I like sandwiches.
You: I get sandwiches from McDonalds, they're great.
Them: Yes, but those are burgers. (The implication being that there are also other kinds of sandwiches.)
You: Yes, burgers are good.
You're not wrong, but you're kind of missing what they're saying.
Enums in Rust can be like enums in C, but they can also be tagged unions. Furthermore, Rust won't automatically cast an enum to an int, so it is a bit harder to make mistakes, even if you're using the C-like ones. That's the advantages they're speaking about. Enums are good and useful in C, it's true. That's why Rust added stuff to make them even more useful.
In my experience it is in fact still a requirement to understand what's happening in order to write clean and fast Rust code. It is possible to satisfy the compiler using a lot of clone() calls and similar shortcuts, but once you understand what data structure is allocated when and where and how the whole ownership principle works in practice you can suddenly avoid a ton of unnecessary heap allocations and other pitfalls. I'd say my experience with Rust improved a lot once I started grasping what's happening in memory and why certain syntax elements exist, as this makes fixing compiler errors more intuitive and less a blind trial and error session with the borrow checker.
Some of Rust's syntax can look weirdly unfamiliar at the beginning, but everything is there for a good reason. Nothing is done implicitly, and much of the pattern matching and Option/Result related stuff is Rust's way of replacing the concept of `null` with thoroughly type-checked expressions.
If having memory errors being compile time errors instead of runtime error leads to more logical errors due to complexity. Wouldn't that imply that using other types of complicated checkers also leads to more logical errors, for example static analysis software or valgrind?
A simple difference would be that, for instance, in Java every object is nullable, whereas in Rust, this is only so when it be declared as such, and the type system requires one to in some capacity first verify of a nullable type that it isn't null, before something meaningful can be done with it.