ACLs also seem to mix concerns. The "private" concept is essentially making life difficult for yourself, but having a built-in mechanism for separating public interface from internal code, that's a bit more than just convention, is useful. For instance, in Common Lisp there's no language-enforced ACL, but when building modules (that may or may not involve a class, or many classes), I assign a package for each module and make it export only the symbols that represent its public interface. In code using that module, this becomes a syntactic difference in a way you refer to these symbols - module:foo means "foo exported from package 'module'", while module::foo means "foo internal to package module". That simple isolation, completely overridable with an extra colon character, is enough to clearly communicate what is and what isn't a part of an abstraction.
Is there a warning when someone overrides that isolation? In C# you can also access private members through reflection and I have seen people use that a lot instead of bothering to understand why the original developer decided to make the variable private.
No, there isn't, because "we're all adults here". But you have to type :: instead of : to do this, which usually tells you something, and you don't have to go through reflection to do this, so such overrides don't cause performance issues. Common Lisp doesn't prevent you from accessing anything.
I wish we he had more adults instead of people fresh from college who think that best practices and things to avoid are obsolete and don’t apply to them :)
That's the unfortunate nature of exponential growth. If the number of programmers doubles, say, every 3 years, that means at any point in time, half of the workforce has less than 3 years of experience.