ponyc: Don't force underscore prefix for private field, method, class etc.
In my opinion, underscore prefix unnecessarily combines identification and visibility concerns into one.
I see the following disadvantages of the prefix:
-
Unnecessary entanglement
Pony language elements have a few dimensions: identity, visibility, type and capability. Identity and visibility are combined into one, even though they are not related. It causes a code entanglement: making package private class visible publicly results in lots of changes in classes of the same package.
-
Code noise
Random example from a code base (tcpconnection.pony):
if not _connected and not _readable and (_pending.size() == 0) then
@asio_event_unsubscribe(_event)
end
I don’t think underscores provide useful information. Furthermore, writing the code requires developer to not only remember the names but also the visibility.
I’m aware this would make a big impact on a current codebase, but the more time pass the harder it is to change. I hope it’s not too late 😃
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 15 (9 by maintainers)
I feel like the implicit name-based privacy thing came back with Go, and I don’t feel like this was well-founded - in my opinion, they were favoring brevity over correctness.
As others pointed out, Pony doesn’t need this - the compiler makes the guarantees.
As Jonas said, when you bring this up with the Go community, they get defensive.
In most OO communities, prefixing private or protected members with an underscore is actually widely regarded as bad practice - others have point out some of the reasons above. I could add to those arguments, but I’m not going to - the reasons not to do this (in languages where the underscore prefix isn’t part of syntax) are well-known and (in my experience) widely accepted.
The questions surrounding this controversy aren’t ever fully addressed - when you call out languages like Go for this, the discussion often ends in name-calling, you get accused of trolling, etc.
Why is it you think that tangling up the member visibility constraints with the method-name is a good idea? The answer is often that it makes it visible at the call-site when you’re accessing something private. This answer naturally leads to other questions though, like “why is that important?”
Or why, then, is it less important to be able to see which type of member I’m accessing? (the dreaded
i_
for integer prefix etc.)Why is it any less important to be able to identify any other circumstances or meta-properties of any accessed member at any call-site?
It’s a controversial choice - controversial because it leads to debates like this, and because not having this feature typically doesn’t lead to any discussion at all. No on complains if you have to use a keyword rather than a naming-convention. No one tends to complain if you can’t see at call-sites whether the accessed member is private, is an integer or string, etc.
Furthermore, nothing prevents authors who insist on making those things visible in their APIs from using such conventions. (Perhaps other than the communities where this is regarded as bad practice.)
Why should it, for example, be a breaking change in my package, if I decide to change the visibility of a member to make it public? Even if you can automate such changes with an IDE, it does affect refactoring and source-control.
Above all, it’s my opinion that making member-names mean something is unnecessary complexity - member names that mean nothing are simpler, because you name them only according to one concern: meaning.
Pony loves to cite correctness. I would claim that visibility and member-names are unrelated issues - making one an effect/artifact of the other, in my opinion, is arguably incorrect.
Since changing this would be a BC break, here’s what I’d propose:
Add a privacy flag.
Retain the
_
convention for backwards compatibility, but in addition allow explicit declaration of private members with a keyword.Deprecate and warn about using the
_
prefix when it’s used to implicitly declare something private, but don’t warn about the_
prefix if the member is also flagged as private.That is, stay away from further opinion-based controversies - let developers continue to use the
_
prefix naming-convention internally in their packages, only forcing them to be explicit about what’s private.This will ensure that private members are declared as private, that public members do not start with an underscore, but will provide the freedom to choose whether you want the controversial
_
prefix on private members internally in your own packages, so likely won’t upset anybody.