@abreslav, welcome back, and thank you for reading and taking the time to respond!
I’m very much interested in hearing more about this comment, particularly with respect to Kotlin. I think I’ve expressed the lessons of my experience with Java pretty thoroughly, and Jesse has done a great job of filling in the gaps.
You referred to DSLs and primary constructors as examples where public-by-default is virtuous.
I understand the argument for primary constructors, but hope that there’s another solution available. Would it be unreasonable for primary constructors to inherit the class’s visibility by default? It would certainly feel natural, I think, given the declarations are adjacent. (It may be obvious here that I’m not a language designer, just an optimist.)
I admit that I don’t understand the issue with DSLs. When defining a public DSL, is it really so onerous to explicitly apply the public modifier? Are public DSLs really so common, especially relative to garden-variety classes and functions, that they should sway the default visibility?
Unfortunately, as I mentioned and Jesse expounded on, public-by-accident has much more potential to create problems than internal-by-accident. We actually will need such a lint rule and will be forced to explicitly apply modifiers to everything, public and internal alike, as a result. In effect, we won’t have a default at all!
On the other hand, if internal were the default it would be perfectly safe to forgo that lint rule and allow use of the default, and most (or at least much) of our code would need no explicit modifier.