Strongly agreed.
> const
I don't have to worry as much about iterator invalidation with containers, because I've documented that I'm not going to change it. Bonus points: I know the documentation isn't lying like it usually is. (Caveat: Someone const_casted it away, and my trust is forever crushed ;_;)
I don't have to scan for side effects to figure out if this const variable is an alias for "the initial size of the container" or "the number of elements remaining to process, which just happens to start as the initial size of the container".
It's clearer if the vector normalization function is "mutate in place" or "return a copy". I've seen enough code that does both that I can't necessarily rely on eyeballing the return type.
I can slap it onto existing, likely side-effecting code, to help make sure I don't miss anything when refactoring to an immutable style, because e.g. I'm preparing for multithreading.
That it helps catch accidental mutation is merely a happy side benefit.
> protected/internal
These are worth it just to unclutter my intellisense, which is how I read most of my documentation on some projects. Because it contains all the documentation, or because the API is straightforward enough that it contains all the necessary documentation.
> static
I've had this both help and harm. I'm typically using C++'s anonymous namespaces instead. I have collisions frequently - localized log methods, error tables, local module allocators, etc.
This is less about "I want to prohibit external calls" and more about "This is throwaway local code that I don't want to painstakingly disambiguate from every other possible chunk of throwaway local code." - I see frequent enough collisions with local log methods (which annotate before calling global log functions), error tables, shorthand aliases to specific allocators, etc.
And now to quote from the article instead:
>> What all of these fine-grained controls have done is to put the focus on software engineering in the small.
I'll certainly agree that fetishizing these micro tools to the detriment of larger system issues is bad. That's more along the lines of "insufficiently wide paranoia" than "the wrong kind" though.
>> There's an architecture used in video games for a long time now where rendering and other engine-level functions are decoupled from the game logic, and the two communicate via a local socket.
You can overcouple via RPC over a socket just fine. Like module level protections, it's a mere speedbump against making a bad decision. There's no panacea.