Four years with Rust
Rust as a language is now realizing the benefits of borrow checking. As the article points out, the syntax doesn&#x27;t have to distinguish between move and assign. The borrow checker will catch a reuse of something already moved away. This turns out to be effective enough in practice that the syntax distinction isn&#x27;t necessary.  That wasn&#x27;t obvious up front.<p>Not having exceptions tends to generate workarounds which are uglier than having exceptions. Rust seems to be digging itself out of that hole successfully.  Early error handling required extremely verbose code.  The &quot;try!()&quot; thing was a hack, because a expression-valued macro that sometimes does an invisible external return is kind of strange. Any macro can potentially return, which is troublesome.  The &quot;?&quot; operator looks cleaner; it&#x27;s known to affect control flow, and it&#x27;s part of the language, so you know it does that. Once &quot;?&quot; is in, it&#x27;s probably bad form for an expression-valued macro to do a return.<p>There&#x27;s still too much that has to be done with unsafe code. But the unsafe situations are starting to form patterns. Two known unsafe patterns are backpointers and partially initialized arrays. (The latter comes up with collections that can grow.) Those are situations where there&#x27;s an invariant, and the invariant is momentarily broken, then restored.  There&#x27;s no way to talk about that in the language. Maybe there should be. More study of what really needs to be unsafe is needed.