> UIKit is an example of a high-level dynamically linked library. Rust isn't ready for that category of use case - but to be fair neither is C++ :)That's fair.
> My point regarding shared data is not about Rust's verbose syntax, but about its unwanted runtime checks which no other languages perform.
FWIW, I think Swift is the only language with implicit checks of this form (for global variables and class properties). Rust only performs such checks if the programmer opts into it by using types like RefCell or Mutex.
> It also has a landmine: if the click callback attempts to call setLimit on the same Counter, it will crash at runtime.
Specifically, the callback will be statically unable to call setLimit unless the programmer decides to use one of those tools, in which case the location of the crash is clear.
> This crash is hard to test for and doesn't add any value: why shouldn't the callback be able to adjust its limit?
That specific case seems like it's okay, but there's a pile of problems in code that is only slightly different. For instance,
- if `clicked` held a reference to an element of a vector stored inside CounterWidget across the callback call, allowing mutation would allow that reference to be invalidated (this is less contrived than it sounds: e.g. iterating through a vector calling the callback for each element has this problem). This is undefined behaviour.
- if the callback enables results in the data being manipulated on multiple threads, you get a data race. (Also undefined behaviour.)
- stepping away from undefined behaviour, there may be things inside the `if` statement after the callback that are relying on the invariant the condition established (e.g. `let remaining = self.limit - self.count` and assuming it will be > 0), the callback can invalidate this in surprising ways, both for the programmer, who didn't expect the circular chain, and for the compiler's, which is thus forced to be defensive/pessimistic, meaning slower code (this is one major reason why Swift adopted exclusivity).