digitalmars.D - Should protection attributes disambiguate?
- Peter Alexander (8/8) Jun 20 2011 I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=61...
- Nick Sabalausky (6/14) Jun 20 2011 If something's private, it's supposed to be an "internal-only" sort of
- Nick Sabalausky (4/22) Jun 20 2011 I'd add that IMO, to do otherwise would break encapsulation (or at least...
- Andrej Mitrovic (4/4) Jun 20 2011 Note that there is a bug with private symbols right now. If you have a
- Jonathan M Davis (18/44) Jun 20 2011 Well, except that access modifiers are _access_ modifiers. They indicate...
- Nick Sabalausky (12/65) Jun 20 2011 Technically, maybe, but there's not much point in seeing it if you can't...
- Andrej Mitrovic (5/6) Jun 20 2011 Maybe the naming of the issue is wrong, but it has to be a bug:
- Kagamin (2/7) Jun 20 2011 Currently access modifiers are not implemented for user-defined types, l...
- Jonathan M Davis (6/14) Jun 20 2011 Oh, yes. That's a bug. But having two symbols which clash where one is p...
- Nick Sabalausky (8/22) Jun 20 2011 Isn't visibility a form of access?
- Jonathan M Davis (10/36) Jun 20 2011 It matters for stuff like NVI (Non-Virtual Inheritance). In that particu...
- so (20/34) Jun 21 2011 Good example, is it only this or are there any others?
- Jonathan M Davis (15/55) Jun 21 2011 ???
- so (7/11) Jun 21 2011 Uh, yeah you are right. I meant something like:
- Jonathan M Davis (18/35) Jun 21 2011 In such a case, the current implementation complains if you try and use ...
- Kagamin (2/3) Jun 20 2011 I can think of a possibility that visibility of private symbols can indi...
- Peter Alexander (14/20) Jun 21 2011 It does break the idea of encapsulation a little, but we have to
I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=6180 Essentially the problem boils down to: - Module A has a private symbol named x - Module B has a public symbol named x - Module C imports A and B and tries to use x unqualified Should the fact that B.x is public and A.x is private disambiguate the usage in module C to use B.x, or is that still an ambiguous unqualified usage of variable x that requires manual qualification/disambiguation?
Jun 20 2011
"Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:itog87$2ed9$1 digitalmars.com...I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=6180 Essentially the problem boils down to: - Module A has a private symbol named x - Module B has a public symbol named x - Module C imports A and B and tries to use x unqualified Should the fact that B.x is public and A.x is private disambiguate the usage in module C to use B.x, or is that still an ambiguous unqualified usage of variable x that requires manual qualification/disambiguation?If something's private, it's supposed to be an "internal-only" sort of thing. Private. Outside its own module, it shouldn't even be visibile and it's existence shouldn't have any effect. So I'd say unqualfied use of x inside C should definitely be allowed and resolve to B.x.
Jun 20 2011
"Nick Sabalausky" <a a.a> wrote in message news:itoiji$2hsk$1 digitalmars.com..."Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:itog87$2ed9$1 digitalmars.com...I'd add that IMO, to do otherwise would break encapsulation (or at least put a big ugly dent in it).I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=6180 Essentially the problem boils down to: - Module A has a private symbol named x - Module B has a public symbol named x - Module C imports A and B and tries to use x unqualified Should the fact that B.x is public and A.x is private disambiguate the usage in module C to use B.x, or is that still an ambiguous unqualified usage of variable x that requires manual qualification/disambiguation?If something's private, it's supposed to be an "internal-only" sort of thing. Private. Outside its own module, it shouldn't even be visibile and it's existence shouldn't have any effect. So I'd say unqualfied use of x inside C should definitely be allowed and resolve to B.x.
Jun 20 2011
Note that there is a bug with private symbols right now. If you have a private class in module A, a public function with the same name in module B and a module C that imports them both, the two names will clash. I've reported this recently.
Jun 20 2011
On 2011-06-20 15:43, Nick Sabalausky wrote:"Nick Sabalausky" <a a.a> wrote in message news:itoiji$2hsk$1 digitalmars.com...Well, except that access modifiers are _access_ modifiers. They indicate whether you can _use_ a particular symbol, not whether you can see it. So, the fact that a symbol is private has _zero_ affect on whether other modules can see it. That being said, the only situation that I can think of where it would cause a problem for private to be used as part part of the disambiguation process would be if you're trying to use a symbol which is private (not realizing that it's private) and end up using a symbol with the same name which you actually can access, and it manages to compile, and you end up using a symbol other than the one that you intended. Now, I wouldn't expect that to be a big problem - particularly since in most cases, the symbols likely wouldn't be able to be used the same and compile - but it is at least theoretically a concern. Personally, I think that the gain in making it so that the compiler can assume that a private symbol doesn't enter into overload sets or whatnot would far outweigh that one, particular problem. - Jonathan M Davis"Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:itog87$2ed9$1 digitalmars.com...I'd add that IMO, to do otherwise would break encapsulation (or at least put a big ugly dent in it).I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=6180 Essentially the problem boils down to: - Module A has a private symbol named x - Module B has a public symbol named x - Module C imports A and B and tries to use x unqualified Should the fact that B.x is public and A.x is private disambiguate the usage in module C to use B.x, or is that still an ambiguous unqualified usage of variable x that requires manual qualification/disambiguation?If something's private, it's supposed to be an "internal-only" sort of thing. Private. Outside its own module, it shouldn't even be visibile and it's existence shouldn't have any effect. So I'd say unqualfied use of x inside C should definitely be allowed and resolve to B.x.
Jun 20 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.1058.1308610718.14074.digitalmars-d puremagic.com...On 2011-06-20 15:43, Nick Sabalausky wrote:Technically, maybe, but there's not much point in seeing it if you can't access it."Nick Sabalausky" <a a.a> wrote in message news:itoiji$2hsk$1 digitalmars.com...Well, except that access modifiers are _access_ modifiers. They indicate whether you can _use_ a particular symbol, not whether you can see it. So, the fact that a symbol is private has _zero_ affect on whether other modules can see it."Peter Alexander" <peter.alexander.au gmail.com> wrote in message news:itog87$2ed9$1 digitalmars.com...I'd add that IMO, to do otherwise would break encapsulation (or at least put a big ugly dent in it).I'm working on a fix to http://d.puremagic.com/issues/show_bug.cgi?id=6180 Essentially the problem boils down to: - Module A has a private symbol named x - Module B has a public symbol named x - Module C imports A and B and tries to use x unqualified Should the fact that B.x is public and A.x is private disambiguate the usage in module C to use B.x, or is that still an ambiguous unqualified usage of variable x that requires manual qualification/disambiguation?If something's private, it's supposed to be an "internal-only" sort of thing. Private. Outside its own module, it shouldn't even be visibile and it's existence shouldn't have any effect. So I'd say unqualfied use of x inside C should definitely be allowed and resolve to B.x.That being said, the only situation that I can think of where it would cause a problem for private to be used as part part of the disambiguation process would be if you're trying to use a symbol which is private (not realizing that it's private) and end up using a symbol with the same name which you actually can access, and it manages to compile, and you end up using a symbol other than the one that you intended. Now, I wouldn't expect that to be a big problem - particularly since in most cases, the symbols likely wouldn't be able to be used the same and compile - but it is at least theoretically a concern.Yea, certainly true. But you can have problems the other way too: A module introduces a new private class/function/variable solely for it's own personal use, and it just happens to have the same name as a public member of some other module. So all the code that uses that public member ends up broken, just because the internal details of something else got changed. So like you, I think the benefits of not letting private stuff participate in overload resolution are well worth the risk of that rare scenario you describe.Personally, I think that the gain in making it so that the compiler can assume that a private symbol doesn't enter into overload sets or whatnot would far outweigh that one, particular problem.
Jun 20 2011
On 6/21/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:That's not necessarily a bugMaybe the naming of the issue is wrong, but it has to be a bug: http://d.puremagic.com/issues/show_bug.cgi?id=6180 If private symbols are not usable, then creating an object of a private class type is a pretty major bug, methinks.
Jun 20 2011
Andrej Mitrovic Wrote:Maybe the naming of the issue is wrong, but it has to be a bug: http://d.puremagic.com/issues/show_bug.cgi?id=6180 If private symbols are not usable, then creating an object of a private class type is a pretty major bug, methinks.Currently access modifiers are not implemented for user-defined types, lol.
Jun 20 2011
On 2011-06-20 17:36, Andrej Mitrovic wrote:On 6/21/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:Oh, yes. That's a bug. But having two symbols which clash where one is private and the other public isn't a bug. It may be a design decision which merits revisiting, but as I understand it, it's a natural consequence of the fact that access modifiers modify access, not visibility. - Jonathan M DavisThat's not necessarily a bugMaybe the naming of the issue is wrong, but it has to be a bug: http://d.puremagic.com/issues/show_bug.cgi?id=6180 If private symbols are not usable, then creating an object of a private class type is a pretty major bug, methinks.
Jun 20 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.1064.1308621500.14074.digitalmars-d puremagic.com...On 2011-06-20 17:36, Andrej Mitrovic wrote:Isn't visibility a form of access? Regardless, I think it's clear that the whole point of a private "access" modifier is to make things *private* and safely encapsulated. The current situation clearly breaks this. And since visibility without access is useless, I don't see any reason to even get into the subtle semantics of "visibility" vs "access" at all.On 6/21/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:Oh, yes. That's a bug. But having two symbols which clash where one is private and the other public isn't a bug. It may be a design decision which merits revisiting, but as I understand it, it's a natural consequence of the fact that access modifiers modify access, not visibility.That's not necessarily a bugMaybe the naming of the issue is wrong, but it has to be a bug: http://d.puremagic.com/issues/show_bug.cgi?id=6180 If private symbols are not usable, then creating an object of a private class type is a pretty major bug, methinks.
Jun 20 2011
On 2011-06-20 19:45, Nick Sabalausky wrote:"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.1064.1308621500.14074.digitalmars-d puremagic.com...It matters for stuff like NVI (Non-Virtual Inheritance). In that particular case, you overload a private function but you can't call it. You couldn't overload it if you couldn't see it. So, there _are_ cases where it matters, and it _is_ an important distinction. It's just that it matters infrequently enough that most people don't realize that there is such a distinction. But distinction or not, I don't see why we couldn't just make it so that any attempt to use a symbol where the clashing symbol can't be used anyway just doesn't clash by ignoring the private symbol in such cases. - Jonathan M DavisOn 2011-06-20 17:36, Andrej Mitrovic wrote:Isn't visibility a form of access? Regardless, I think it's clear that the whole point of a private "access" modifier is to make things *private* and safely encapsulated. The current situation clearly breaks this. And since visibility without access is useless, I don't see any reason to even get into the subtle semantics of "visibility" vs "access" at all.On 6/21/11, Jonathan M Davis <jmdavisProg gmx.com> wrote:Oh, yes. That's a bug. But having two symbols which clash where one is private and the other public isn't a bug. It may be a design decision which merits revisiting, but as I understand it, it's a natural consequence of the fact that access modifiers modify access, not visibility.That's not necessarily a bugMaybe the naming of the issue is wrong, but it has to be a bug: http://d.puremagic.com/issues/show_bug.cgi?id=6180 If private symbols are not usable, then creating an object of a private class type is a pretty major bug, methinks.
Jun 20 2011
On Tue, 21 Jun 2011 06:04:28 +0300, Jonathan M Davis <jmdavisProg gmx.com> wrote:It matters for stuff like NVI (Non-Virtual Inheritance). In that particular case, you overload a private function but you can't call it. You couldn't overload it if you couldn't see it. So, there _are_ cases where it matters, and it _is_ an important distinction. It's just that it matters infrequently enough that most people don't realize that there is such a distinction. But distinction or not, I don't see why we couldn't just make it so that any attempt to use a symbol where the clashing symbol can't be used anyway just doesn't clash by ignoring the private symbol in such cases. - Jonathan M DavisGood example, is it only this or are there any others? I am asking because i think this particular use case doesn't justify visibility but not access. If i got it right, we are talking about something like this: module base1; private import base; struct base1 : base { } module base2; import base1; struct base2 : base1 { } Shouldn't compiler just issue an error whenever base1 accessed outside of the module it belongs? With its current state, it just encourages bad design as far as i can see. First of all inheriting from a class/interface/struct that is imported private implies this new class is going to be an implementation detail, hidden from user. If it wasn't intended, why would you import it private?
Jun 21 2011
On 2011-06-21 05:40, so wrote:On Tue, 21 Jun 2011 06:04:28 +0300, Jonathan M Davis <jmdavisProg gmx.com> wrote:??? private import a; and import a; are identical. There is no difference. When you import that doesn't affect any modules that import you. Now, making an import _public_ affects other modules, because then anyone who imports you also imports the other module, but imports are private by default. So, I don't understand what you're saying here. The compiler does issue an error when you try and use a symbol which is private to another module. The issue here is that if there's another symbol which clashes which you _can_ access, the compiler forces you to give its full path instead of assuming that you mean the public one (which you _can_ use) and not the private one (which you can't). - Jonathan M DavisIt matters for stuff like NVI (Non-Virtual Inheritance). In that particular case, you overload a private function but you can't call it. You couldn't overload it if you couldn't see it. So, there _are_ cases where it matters, and it _is_ an important distinction. It's just that it matters infrequently enough that most people don't realize that there is such a distinction. But distinction or not, I don't see why we couldn't just make it so that any attempt to use a symbol where the clashing symbol can't be used anyway just doesn't clash by ignoring the private symbol in such cases. - Jonathan M DavisGood example, is it only this or are there any others? I am asking because i think this particular use case doesn't justify visibility but not access. If i got it right, we are talking about something like this: module base1; private import base; struct base1 : base { } module base2; import base1; struct base2 : base1 { } Shouldn't compiler just issue an error whenever base1 accessed outside of the module it belongs? With its current state, it just encourages bad design as far as i can see. First of all inheriting from a class/interface/struct that is imported private implies this new class is going to be an implementation detail, hidden from user. If it wasn't intended, why would you import it private?
Jun 21 2011
On Tue, 21 Jun 2011 18:43:51 +0300, Jonathan M Davis <jmdavisProg gmx.com> wrote:??? private import a; and import a;Uh, yeah you are right. I meant something like: module base1; private struct base; struct base1 : base { }
Jun 21 2011
On 2011-06-21 09:00, so wrote:On Tue, 21 Jun 2011 18:43:51 +0300, Jonathan M Davis <jmdavisProg gmx.com> wrote:In such a case, the current implementation complains if you try and use base, which is exactly what it should be doing. It'll tell you that base is private and that you don't have access to it. If it were completely hidden, then the error message would end up saying something about base not existing, which could be far more confusing, since base _does_ exist. The issue here is that if you had your own base which you imported from another module, the compiler is going to complain about that base and base1.base clashing instead of assuming that you meant your base, since base1.base is private. All that is required here is adjusting how symbols collisions are dealt with when one of the symbols is private. There's no need to adjust how access modifiers work globally. And there are _definitely_ people out there who think that NVI justifies visibility without access. But regardless of that, I believe that that's how public and private work in every C-derived language which has them. The exact implications of that may very from language to language depending on what they do or don't allow you to do, but as far as I know, access modifiers are always _access_ modifiers and not visibility modifiers. - Jonathan M Davis??? private import a; and import a;Uh, yeah you are right. I meant something like: module base1; private struct base; struct base1 : base { }
Jun 21 2011
Nick Sabalausky Wrote:And since visibility without access is uselessI can think of a possibility that visibility of private symbols can indicate wrong access modifiers, though it's difficult to figure out a use case.
Jun 20 2011
On 21/06/11 3:45 AM, Nick Sabalausky wrote:Isn't visibility a form of access? Regardless, I think it's clear that the whole point of a private "access" modifier is to make things *private* and safely encapsulated. The current situation clearly breaks this. And since visibility without access is useless, I don't see any reason to even get into the subtle semantics of "visibility" vs "access" at all.It does break the idea of encapsulation a little, but we have to consider the side effects: As Jonathan says, it's possible that someone could try to use a private symbol and instead get a public symbol from another module. Depending on the situation, this could introduce subtle incorrect behavior that is difficult to detect. It's rare, but it could happen. You rightly argued the other way that someone could add a private symbol, which then causes user code to fail to compile due to a ambiguity. That sucks, but it is just an inconvenience that is easily solved by qualifying usage of the symbol. There is no possibility of subtle, difficult-to-detect behavior. I'm kind of on the fence with this. There's definitely merit to both sides of the argument.
Jun 21 2011