4 ms·
In my view the purpose of const/protected/internal/static etc is not so much to prevent mistakes by myself or others, but to embed in my code a 'living document
by AdeptusAquinas 12y ago
In my view the purpose of const/protected/internal/static etc is not so much to prevent mistakes by myself or others, but to embed in my code a 'living documentation', enforced by the compiler.
If I mark a method as internal, that means I intend it for reuse within the library but don't expect it to be used by any external caller, which means another developer can come along and make changes to it without needing to worry about anything outside the library (short of those in C# using [InternalsVisibleTo] or similar, which hopefully is restricted heavily to obvious test projects).
By decorating my code appropriately, I don't need to write comments most of the time, which means I don't run the risk or filling my code with out-of-date or poorly understood annotations that become useless almost as soon as I finish writing them.
- rdtsc 12y agoI agree with this. The code is not just a message to the compiler to build the binary/bytecode, it is also a message to other programmers. As such there is value in annotating things in that manner. Even in Python, a very dynamic language, there is a convention that methods that start with _ are private. And I often also separate them into a different (bottom) section with a big header saying this is the private block of methods. So in that case there isn't a compiler rule but rather a common convention (which is kind of a step above comments if you wish).
- rpedroso 12y agoIf you want to enforce this more stringently, you can even prefix methods with __ (double underscore). Python will mangle the name: __mydef -> _myClass__mydef You can, of course, still access the method, but it's very useful for keeping implementation details of a base class out of a subclass. This way, your subclass can have its own `mydef` without overriding the base class.
- chipsy 12y agoI disagree with the exact statement but also agree with its sentiment. The functionality of a language should be applied for a specific engineering reason, and protection features are sensible at the right scale. But at no point does it replace documentation efforts. You can surface the simplest possible interface to your users and still have questions and concerns that need supplementary text.
- MaulingMonkey 12y agoStrongly 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_cast<>ed 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.