traits getProtection

Jonathan M Davis jmdavisProg at gmx.com
Wed Apr 4 01:41:24 PDT 2012


On Wednesday, April 04, 2012 09:04:41 deadalnix wrote:
> Le 04/04/2012 04:48, Jonathan M Davis a écrit :
> > On Tuesday, April 03, 2012 08:23:49 deadalnix wrote:
> >> Le 02/04/2012 22:59, Simen Kjærås a écrit :
> >>> On Mon, 02 Apr 2012 20:02:20 +0200, deadalnix<deadalnix at gmail.com>  
wrote:
> >>>>> Now, there are a number of people very unhappy about this state of
> >>>>> affairs and
> >>>>> want private to hide symbols as well (personally, I think that the
> >>>>> fact that
> >>>>> it makes private aliases effectively useless is reason enough to
> >>>>> seriously
> >>>>> reconsider the current behavior), but I don't know if there's any
> >>>>> real chance
> >>>>> of convincing Walter or not.
> >>>> 
> >>>> This would be a huge mistake. For instance, private method are
> >>>> sometime meant to be overridden in subclasses, which is impossible if
> >>>> symbol is inaccessible.
> >>>> 
> >>>> NVI for instance would be impossible in such a situation.
> >>> 
> >>> NVI is perfectly possible with protected.
> >> 
> >> You'll loose the ability to define a function, without being able to
> >> call it.
> > 
> > Except that that doesn't even actually work as discussed in this thread:
> > 
> > http://www.digitalmars.com/d/archives/digitalmars/D/Re_Module-
> > level_accessibility_118209.html#N118329
> > 
> > The derived class overrode the function, so it can call it. It may not be
> > able to call the base class version, but it can call its own.
> 
> It shouldn't be able to do so. This should be reserved for protected
> methods.

Well, that's the way that it works in C++. And it makes sense if you think 
about it. The derived class' method is private to _it_, not the base class, so 
it can still call it, even if it can't call the base class version.

> > Sure, NVI is great, but it works just as well with protected. private
> > doesn't actually prevent you from calling the function in the derived
> > class, and even if it did, it's _not_ worth the cost of making private
> > virtual by default. And as D lets the compiler control virtuality, unlike
> > C++, it doesn't make any sense to make it so that the programmer can
> > specifically make a private function virtual to work with NVI. So, it
> > just makes more sense to use protected to do NVI.
> 
> Visibility and virtuality are 2 completely orthogonal concerns. Mixing
> both is a bad design decision, what ever is the rational behind it.
> Separation of concerns is more important.

They are and they aren't. There are major issues in allowing the overriding of 
non-virtual functions. It's far less error-prone to simply make it so that a 
class' member functions are always virtual unless the compiler can determine 
that it can make them non-virtual (which can only happen when they're final and 
don't override anything). D took the same route as Java in this regard. And 
because it took that route, the programmer has _zero_ control over the 
virtuality of a function, and it's very much tied to the access level of a 
function. That design decision is _not_ going to be changed, so the virtuality 
of a function is defined by its access level.

> Plus, this isn't a real issue, because the final keyword exists.

It's a _huge_ issue, because it means that nearly every single private 
function in a class in D will need to be marked with final in order for it to 
be non-virtual and inlinable. The default becomes inefficient, and all just for 
NVI.

> At the end, for performance concerns, what we want is that the compiler
> or the linker were able to finalize methods that have no override, not
> some dirty trick that break larger more important conception principles.

Because of how the compilation model works, that's impossible. No class can 
know all of its derived classes. Not only are classes compiled completely 
independently of their derived classes, but derived classes could be linked in 
dynamically at runtime, and those classes could have been written long after 
the base class was written and compiled. So, unless the programmer explicitly 
marks a function as final, there's no way that the compiler can know that that 
function won't be overridden.

> > Now, it may be different with interfaces. TDPL specifically talks about
> > using private for NVI with _interfaces_, not classes. Doing that sort of
> > thing with interfaces requires special treatment already, and it doesn't
> > affect efficiency like making private always virtual would, so that
> > should be okay. In the general case though, it's just far better to use
> > protected to do NVI with classes and let private be non-virtual and
> > therefore efficient by default rather than inefficient by default.
> > 
> > - Jonathan M Davis
> 
> It is not that simple. First, it introduce an inconsistency between
> interfaces and classes for no real reasons. The only difference between
> classes and interfaces should be that interface cannot have member data,
> and you can inherit from multiple interfaces. Interface have been
> created to solve the problems that exists for multiple inheritance, and
> that is enough to solve that problem. Everything else is, again, lack of
> separation of concerns.

private is _not_ going to become virtual in classes. I believe that Walter has 
stated that it will remain non-virtual (though I'd have to dig through the 
newsgroup for the exact quote). The only question is how to handle it in 
interfaces, and as far as I know, the intention is to make interfaces follow 
TDPL with regards to private.

> Second, the same method can be declared in the base class and in an
> interface, and in this case, we cause compile error for nothing.

Why would there be a compilation error? The base class cannot call the 
interface's private function, so any reference to that function would be the 
base class' function.

- Jonathan M Davis


More information about the Digitalmars-d mailing list