Again, that is provided in higher level languages by abstractions over mutable state, such as STM (example: Clojure's Refs and Atoms [0]). And/or by making immutability the default.
Neither that, memory safety, nor forcing you to deal with optionality is unique to Rust.
The big difference is that Rust manages to do these things while also having similar performance characteristics as C/C++. The trade-off is that the programmer has to explicitly deal with these issues.
I personally haven't yet seen a safety language feature of Rust that is not somehow available in other languages with similar claims. I would appreciate learning otherwise if I'm missing something.
I think the only feature that would push Rust to being at the forefront would be "const generics" [1] or true dependent types down the line.
Does Clojure actually force you to use those abstractions though? Many languages provide concurrency primitives, but Rust will fail to compile if you try to use non-concurrency safe objects from multiple threads.
In short: it is inconvenient to use mutable state and unidiomatic to not use the STM.
The long version is that you could use 'set!' with Vars. But this is very much an avoided practice. Another caveat is that Clojure is hosted (primarily JVM and JS), so any code you call via interop has the characteristics of the host target.
But idiomatic Clojure uses at least Atoms or Refs and even those are discouraged for anything else than storing state, all the algorithmic (transformation, branching and so on) code follows the FP paradigm.
A Rust analogy is the 'unsafe' escape hatch. You can use it but it would be unidiomatic, inconvenient and in most cases unnecessary.
That comment is somewhat disingenuous. It is like saying that Rust is an unsafe language, because of 'unsafe' or the mere fact that you can just use stringly types for everything.
Both using 'unsafe' and using String instead of an Enum would compile without runtime guarantees. But such code would stick out.
Right. The main advantage of Rust is that its thread safety is opt-out (unsafe) rather than opt-in (remember to use the right data structures / locks).
This is sort of a question, but doesn’t Rust refuse to compile even when you use non-concurrency safe objects in a single thread?
I think that is the case
Rust types have markers (Send, Sync) that tell the compiler whether they can be moved across threads, and whether they can be simultaneously accessed across threads.
These markers are irrelevant in a single-threaded scenario.
It's not purely about those markers. Many people also believe that the only issue with aliasing is when threads come into play, but that's not the case. Rust also prevents mutable aliasing even in non-threaded cases for this reason.
Is there any explanation of this? Specifically i would like to understand how a single mutable reference is required for correctness in a single thread scenario.
I’ve googled everywhere but I can’t find a single source of information that completely explains this, possibly showing realistic source code and elaborating the way it could generate memory errors or be miscompiled in case of multiple mutable references.
Agreed, the novelty is doing it in the core language (unsafety is opt-in, not the other way around) and without sacrificing performance.
Any language that relies on GC and avoids mutation e.g. by extrmely inefficient data structures (persistent data structures and other immutable data) obviously achieve mostly the same level of safety but at a huge cost.
> Agreed, the novelty is doing it in the core language (unsafety is opt-in, not the other way around) and without sacrificing performance.
Unsafe code blocks as opt-in in systems languages appeared for the first time in 1961, followed by multiple variations of it since then, far from being a novelty by now.
No Rust is not “just as unsafe”, it keeps all its unsafety inside specific blocks where the burden to avoid (or handle bad behavior from) e.g. races, type safety or memory management is placed on the developer. In my C# programs I have to handle the risk of races with my head, in the entire codebase.
One might argue that “well those small parts of a rust program are as unsafe as the entire C# program” but that would be a completely nonsensical argument so I’m going to give you the benefit of the doubt that’s not what you meant.
Only because apparently you don't make proper use of Dataflow and TPL libraries.
Besides, the recent security exploits have proven that it is time to go back into multi-processes, and here Rust doesn't have anything to offer.
So one should tune a bit down the tone of labelling all the other languages as unsafe, even managed ones, industry standards like SPARK, or system research languages like ATS.
What would you use where correctness the top priority? Haskell? For the best thing about Rust isn't the performance (although that's great). It's just how reliable my Rust projects have been in production. If you wanted this level of reliability from another language, you'd have to write tests to cover all the possible failure cases. Which is much more time consuming than having the compiler point out all the possible failure points for you.
If correctness is the top priority, then formal verification methods and/or SPARK and/or specialized subsets of C with the tooling that comes with them for safety projects.
Rust and Haskell and standard C and C++ are all non-starters.
If by "correctness" you mean what I call "small-c correctness" ("this reference won't be null", "this function call doesn't write to the database") then Haskell is currently best-in-class. If by correctness you mean what I call "big-V Verification" then the sibling answer[1] is better for you.
One example that comes to mind is type state [0]. I'm not aware of any other language (including those with support for dependent types, like Agda) where these properties can be checked without external static analysis tools and the problems they bring.
Neither that, memory safety, nor forcing you to deal with optionality is unique to Rust.
The big difference is that Rust manages to do these things while also having similar performance characteristics as C/C++. The trade-off is that the programmer has to explicitly deal with these issues.
I personally haven't yet seen a safety language feature of Rust that is not somehow available in other languages with similar claims. I would appreciate learning otherwise if I'm missing something.
I think the only feature that would push Rust to being at the forefront would be "const generics" [1] or true dependent types down the line.
[0] https://en.wikipedia.org/wiki/Software_transactional_memory
[1] https://github.com/rust-lang/rust/issues/44580