Default thread-safe data structure ( by default not making it thread-safe) - multithreading

I'm learning about multithreading and I came up to the point to see if there's any thread-safe data structure by default, I looked on the internet and I found only one statement.
immutable is thread-safe.
but actually, I'm looking for a general question, like is the tree/stack/graph/linked-list...etc is thread-safe by default?
another question does the immutable are different from language to language? I mean for example string is immutable in Java, but does that mean it might be mutable in C/C++ for example?
Before closing my question, just let me be clear, I know how to make any data structure thread-safe, but I'm asking if there's any by default a thread-safe

Related

Is it possible to find a list of all smart pointers in Rust Standard Library? If so how?

I was wondering, is there a way to know the list of all smart pointers in Rust std?
I know String and Vec<T> are smart pointers, and reading Chp. 15 of the Rust book, I am learning about Box<T>, Rc<T>, Ref<T> and RefMut<T>
I was just wondering, is there a place to know all the available smart pointers in Rust's std?
I don't think an all-encompassing list would be particularly useful since there are lots (especially many which serve more as an implementation detail of another type). If you really want a complete list of everything that's technically a smart pointer, then as eggyal pointed out in a comment on your question you could browse the implementors of Deref, but that will probably give you more noise than useful information. I've listed some of the most common and useful ones below:
Box<T> - a unique pointer to an object on the heap. Analogous to C++'s std::unique_ptr.
Rc<T>/Weak<T> - a shared pointer that provides shared ownership of a value on a single thread. This smart pointer cannot be sent between threads safely since it does not use atomic operations to maintain its refcount (the compiler will make sure you don't accidentally do this).
Arc<T>/Weak<T> - very similar to Rc except it uses atomic operations to update its refcount, and thus is thread-safe. Similar to std::shared_ptr.
Vec<T>/String/PathBuf/OsString et al. - all of these are smart pointers for owning dynamically allocated arrays of items on the heap. Read their documentation for more specific details.
Cow<'a, B> - a clone-on-write smart pointer. Useful for when you have a value that could be borrowed or owned.
The list above isn't the full picture but it will get you very far with most of the code you write.
As you've noted there are other smart pointers like Ref and MutexGuard. These are returned by types with interior mutability, and usually have some kind of specific behavior on drop, such as releasing a lock or decrementing a refcount. Usually you don't interact with these types as much, but you can read their documentation on an as-needed basis.
There is also Pin<T>, but this smart pointer is notoriously hard to understand and really only comes up in conversations about the implementation details of futures and generators. You can read more about it here.

Why is Box called like that in Rust?

Box<> is explained like this on the Rust Book:
... allow you to store data on the heap rather than the stack. What remains on the stack is the pointer to the heap data.
With a description like that, I would expect the described object to be called Heap<> or somethingHeapsomethingelse (DerefHeap, perhaps?). Instead, we use Box.
Why was the name Box chosen?
First, Heap is a very overloaded term, and importantly a heap is an abstract datastructure often used to implement things like priority queues. Having a type called Heap which is not a heap would be extremely confusing, a good reason to avoid that.
Second, "box" is related to the concept of "boxing" or "boxed" objects, in languages which strongly distinguish between value and reference types e.g. Java or Javascript: https://en.wikipedia.org/wiki/Object_type_(object-oriented_programming), in those a "boxed" type is the heap-allocated version of a value type e.g. int/Integer in java, or number/Number in Javascript.
Rust's Box performs an operation which is similar in spirit. Box also originally had a built-in "lifting" operator called box (it's still an internal operation and was originally planned to be stabilised for placement new), as such "box"/"boxing" makes sense linguistically in a way "heap"/"heaping" really does not (as "heaping" hints at a lot of things being put on a heap).

What functionality does it makes sense to implement using Rust enums?

I'm having problem understanding the usefulness of Rust enums after reading The Rust Programming Language.
In section 17.3, Implementing an Object-Oriented Design Pattern, we have this paragraph:
If we were to create an alternative implementation that didn’t use the state pattern, we might instead use match expressions in the methods on Post or even in the main code that checks the state of the post and changes behavior in those places. That would mean we would have to look in several places to understand all the implications of a post being in the published state! This would only increase the more states we added: each of those match expressions would need another arm.
I agree completely. It would be very bad to use enums in this case because of the reasons outlined. Yet, using enums was my first thought of a more idiomatic implementation. Later in the same section, the book introduces the concept of encoding the state of the objects using types, via variable shadowing.
It's my understanding that Rust enums can contain complex data structures, and different variants of the same enum can contain different types.
What is a real life example of a design in which enums are the better option? I can only find fake or very simple examples in other sources.
I understand that Rust uses enums for things like Result and Option, but those are very simple uses. I was thinking of some functionality with a more complex behavior.
This turned out to be a somewhat open ended question, but I could not find a useful response after searching Google. I'm free to change this question to a more closed version if someone could be so kind as to help me rephrase it.
A fundamental trade-off between these choices in a broad sense has a name: "the expression problem". You should find plenty on Google under that name, both in general and in the context of Rust.
In the context of the question, the "problem" is to write the code in such a way that both adding a new state and adding a new operation on states does not involve modifying existing implementations.
When using a trait object, it is easy to add a state, but not an operation. To add a state, one defines a new type and implements the trait. To add an operation, naively, one adds a method to the trait but has to intrusively update the trait implementations for all states.
When using an enum for state, it is easy to add a new operation, but not a new state. To add an operation, one defines a new function. To add a new state, naively, one must intrusively modify all the existing operations to handle the new state.
If I explained this well enough, hopefully it should be clear that both will have a place. They are in a way dual to one another.
With this lens, an enum would be a better fit when the operations on the enum are expected to change more than the alternatives. For example, suppose you were trying to represent an abstract syntax tree for C++, which changes every three years. The set of types of AST nodes may not change frequently relative to the set of operations you may want to perform on AST nodes.
With that said, there are solutions to the more difficult options in both cases, but they remain somewhat more difficult. And what code must be modified may not be the primary concern.

Why is immutability enforced in Rust unless otherwise specified with `mut`?

Why is immutability forced in Rust, unless you specify mut? Is this a design choice for safety, do you consider this how it should be naturally in other languages?
I should probably clarify, I'm still a newbie at Rust. So is this a design choice related to another feature in the language?
The Rust-Book actually addresses this topic.
There is no single reason that bindings are immutable by default, but we can think about it through one of Rust’s primary focuses: safety. If you forget to say mut, the compiler will catch it, and let you know that you have mutated something you may not have intended to mutate. If bindings were mutable by default, the compiler would not be able to tell you this. If you did intend mutation, then the solution is quite easy: add mut.
There are other good reasons to avoid mutable state when possible, but they’re out of the scope of this guide. In general, you can often avoid explicit mutation, and so it is preferable in Rust. That said, sometimes, mutation is what you need, so it’s not verboten.
Basically it is the C++-Mantra that everything that you don't want to modify should be const, just properly done by reversing the rules. Also see this Stackoverflow article about C++.

How do Rust's ownership semantics relate to uniqueness typing as found in Clean and Mercury?

I noticed that in Rust moving is applied to lvalues, and it's statically enforced that moved-from objects are not used.
How do these semantics relate to uniqueness typing as found in Clean and Mercury? Are they the same concept? If not, how do they differ?
The concept of ownership in Rust is not the same as uniqueness in Mercury and Clean, although they are related in that they both aim to provide safety via static checking, and they are both defined in terms of the number of references within a scope. The key differences are:
Uniqueness is a more abstract concept. While it can be interpreted as saying that a reference to a memory location is unique, like Rust's lvalues, it can also apply to abstract values such as the state of every object in the universe, to give an extreme but typical example. There is no pointer corresponding to such a value - it cannot be opened up and inspected within a debugger or anything like that - but it can be used through an interface just like any other abstract type. The aim is to give a value-oriented semantics that remains consistent in the presence of statefulness.
In Mercury, at least (I can't speak for Clean), uniqueness is a more limited concept than ownership, in that there must be exactly one reference. You can't share several copies of a reference on the proviso that they will not be written to, as can be done in Rust. You also can't lend a reference for writing but get it back later after the borrower has finished with it.
Declaring something unique in Mercury does not guarantee that writing to references will occur, just that the compiler will check that it would be safe to do so; it is still valid for an implementation to copy the contents of a unique reference rather than update in place. The compiler will arrange for the update in place if it deems it appropriate at its given optimization level. Alternatively, authors of abstract types may perform similar (or sometimes drastically better) optimizations manually, safe in the knowledge that users will be forced to use the abstract type in a way that is consistent with them. Ownership in Rust, on the other hand, is more directly connected to the memory model and gives stronger guarantees about behaviour.

Resources