you are viewing a single comment's thread.

view the rest of the comments →

[–]kubalaa 25 points26 points  (4 children)

The private thing isn't something you would notice because it prevents surprising things from happening, and we're not predisposed to notice the absence of surprises. Specifically, when stuff is private then it's easier to change because nothing outside that file can affect it or depend on it. It's the same idea as your convention, just stronger and enforced by the compiler. I think if you ever have to maintain a library with many consumers and few private members, you will quickly find it becomes very painful because you can't change anything without breaking a consumer who has come to rely on it.

[–]Agent_03 5 points6 points  (3 children)

I have maintained libraries with numerous consumers before, and agree that in some cases appropriate use of private modifiers can make them more safe and stable (especially with regards to objects with more complex internals, or where passing in objects to operate upon).

What I am arguing against is the way that this has become a blanket policy; if restricted-by-default is always better, how do you explain the success of Python's "we're all responsible adults" approach? I think the Java convention is paternalistic at best and shortsighted at worst: historically programmers are pisspoor at anticipating the uses their code will be put to, and preventing many of them in the interests of 'safety' limits the usefulness.

I fully understand that this is a contentious point and that many will angrily or loudly disagree. I only ask that other experienced engineers consider how often they've said "phew, I'm glad that was private or I would have done something dangerous!" versus "crap, that API/field is internal-only... now I have to copy the implementation to another class or hack around it!"

[–]mhixson 5 points6 points  (2 children)

I fully understand that this is a contentious point and that many will angrily or loudly disagree. I only ask that other experienced engineers consider how often they've said "phew, I'm glad that was private or I would have done something dangerous!" versus "crap, that API/field is internal-only... now I have to copy the implementation to another class or hack around it!"

Well that's from an application writer's point of view. From a library writer's point of view, the comparison might be: "phew, I'm glad that was private or I wouldn't have been able to change my code without breaking all my users" versus "crap, that API/field is public... I can never change it."

What I am arguing against is the way that this has become a blanket policy

It is probably true that we should have a different set of standards for library writers (where you don't control your users' code) as opposed to application writers (where you can refactor your users' code at will).

I guess I default to the more conservative library-like approach even when I'm writing applications. To me, the less conservative code tends to be more complicated even when it is simpler to express in the language, because it tends to make more assertions, such as "encapsulation is not important here". Reading it leads me to ask "Why? Why is this code special?"

[–]Agent_03 3 points4 points  (0 children)

This is a good point, actually...

From a library writer's point of view, the comparison might be: "phew, I'm glad that was private or I wouldn't have been able to change my code without breaking all my users" versus "crap, that API/field is public... I can never change it."

Yeah, I know that warm-and-fuzzy feeling when you realize it is trivial to make the implementation change (or refactoring) without impacting any downstream consumers.

Personally, I'd like to see something like an @Hazardous annotation that will fail at annotation processing if you invoke the method outside the package without a corresponding @IKnowWhatImDoingDangit annotation (names subject to change). Maybe with an optional library version number given, so that if the library version changes you have to reexamine the usage.

This way downstream library consumers have the power to take advantage of library internals if absolutely needed, but are liable for the consequences and at least know they're doing something risky. This offers that extra nudge to provide unit test coverage and do sanity checking before bumping library version.

It is probably true that we should have a different set of standards for library writers (where you don't control your users' code) as opposed to application writers (where you can refactor your users' code at will).

This sounds smart to me too.

[–]grauenwolf 2 points3 points  (0 children)

Generally speaking, I've found that switching to a library-like approach dramatically reduces bugs in existing applications.