One thing I can fully agree on is that it sucks when someone contributes code and your library breaks a year later because they snuck in an undocumented internal Base
method to make something work but didn’t make a note or add a check to the tests. It makes sense to want some guard against that beyond proofreading code at 100% efficiency.
It just doesn’t make sense to appropriate OOP access modifiers for this, Julia doesn’t have classes for access modifiers to encapsulate. Roughly speaking, OOP encapsulation designates what components of a class are accessible by other classes (public methods and few fields) and what are confined implementation details (private fields, methods, even nested classes). It’s not the same, but a non-OOP encapsulation is accomplished by modules separating global scopes, export
ing select names, or import
ing select names. That’s why export
ed names came up in the thread as a hint of public API (though still not as authoritative as documentation).
The talk about access modifiers is suggesting that we should apply to multimethods in modules something designed for members in classes. There’s a lot wrong with this:
- Internals aren’t confined to their home module, they’re free to be exported within the package to the convenience of the developer and out of the users’ sight.
- The unit in which an internal operates is not a module, it’s the package. So you could invent access modifiers on a package level…if you’re prepared to sacrifice the ability to inspect and test internals easily. There’s also a complicated unsettled debate on how to develop and test (or not) private members.
- Unlike a singly dispatched method confined to a class, a multimethod’s definition can be scattered, even across packages. What happens when some methods are marked
@private
and the others are marked@public
? This straightforward inspiration is just a footgun. - What about global variables and macros? Macros aren’t even variables or instances.
There’s been some talk about informal conventions like leading underscores, but I’m not sure it’ll solve the issue at hand. It saves someone from checking documentation or export
s to know if something is public vs internal, but a proofreader can easily overlook it anyway. Without printing warnings or throwing errors, this’ll only make a very rare mistake somewhat easier to spot. And remember that all our internals would have leading underscores, so when you search the text ._
, most of it would be your internals. And if we want to make an internal public in the next version? Time to find-replace-all every file.