This is clearly a better solution compared to the average language but what if you forget to mark a field or object as guarded?
Just take a look at the basic problem of multi-threading: two threads write to the same memory location. This situation is unpredictable and there never allowed to happen.
There are three general strategies to deal with this: immutability, mutexes and linear types to ensure there is only one reference with write capability.
The latter makes writing code that is not thread-safe impossible at compile time without sacrificing efficiency and is used by at least two programming languages that I know of: Ponylang and Rust. For me impossible vs "oops forgot to guard it" are worlds apart. The compiler will inform you that it is not thread-safe and then you can decide to use a different solution like a mutex if necessary.
Just take a look at the basic problem of multi-threading: two threads write to the same memory location. This situation is unpredictable and there never allowed to happen. There are three general strategies to deal with this: immutability, mutexes and linear types to ensure there is only one reference with write capability.
The latter makes writing code that is not thread-safe impossible at compile time without sacrificing efficiency and is used by at least two programming languages that I know of: Ponylang and Rust. For me impossible vs "oops forgot to guard it" are worlds apart. The compiler will inform you that it is not thread-safe and then you can decide to use a different solution like a mutex if necessary.