On 8/11/2011 4:10 PM, Tipp, Brandon P wrote:
> [...]
>
> I don't think that we'd want to disallow virtual (abstract)
> classes which implement interfaces.
>
> */[Alsop, Thomas R] I never said this and actually agree with you. I
> just think that when you 'implement' an interface class, you have to
> provide the full definition, regardless of it being in an abstract
> class or non-abstract class. Otherwise we run into this inherit
> causality effect. /*
>
> An abstract class
> should be allowed to be partial in the sense of not defining
> implementations but must be complete in terms of
> defining prototypes that satisfy the contract obligations
> (whether directly or through inheritance).
>
> */[Alsop, Thomas R] But isn't this just a cut-n-paste. Please convince
> me of the point of doing this. /*
>
>
> */[Tipp, Brandon P] By declaring a virtual class as implementing an
> interface class, you add assignment and casting capabilities (class
> compatibility) that you don't get with cut-and-paste. An abstract
> class shouldn't be forced to provide an implementation for any method;
> that defeats the purpose of an abstract class. I've previously
> removed language regarding a class "inheriting" virtual method
> prototypes from implemented interface classes; I'm not sure that I see
> a big deal about "effectively" inheriting it, but I can add language
> that/*
>
> */"A virtual class shall define or inherit a method prototype or
> implementation for each method prototype from each interface class
> that it implements."/*
>
> */Which requires a prototype or definition to be present where an
> interface class is implemented by an abstract class or/*
>
> */"Any method of an interface class may be called on a variable of a
> type which implements that interface class." /*
>
> */Which explicitly allows the method call without requiring a
> prototype or definition to be present./*
>
> */If a prototype is required, then adding an implements could result
> in compile errors on the abstract class due to missing prototypes even
> if there is a definition further down the line. Fixing those compile
> errors would require any non-virtual methods down the line to
> implicitly become virtual. If the prototype is not required, then
> adding an implements could result in a compile errors on the
> non-abstract classes which inherit the abstract class if no definition
> is provided. Furthermore, it could implicitly/silently change the
> behavior of non-virtual methods to virtual without any errors
> reported. Pick your poison./*
>
>
GORD: Right. I'll going to go back to my earlier statement -- adding
"implements" shouldn't change *behavior*. So, yes, you might get
compile errors if an abstract class didn't have a prototype for an
implemented method, but at least you find out early. If you don't do
that, you can get behavior changes in the existing class code which then
becomes a run-time debug exercise. Personally, I prefer compile/elab
errors to run-time debug sessions. So, I'd prefer to require that the
prototypes exist (either by inheritance or explicitly required).
>
> In 18, the base method is NOT virtual and as you point
> out in your comments on 17, we would not want it to become
> implicitly virtual by way of "der" implementing the interface
> class. But the committee's discussion of 16 would require
> "der" to provide a prototype (which would hide the non-virtual
> base method) or would generate an error since the base method
> is non-virtual. That is clean and doesn't require any particular
> change or special consideration of the normal class rules.
>
> */[Alsop, Thomas R] Hold on, are you saying the committee wants to
> allow the abstract class to use 'implements' to do the following.
> This is the cut and paste of the IC prototype into the abstract class
> in order to "satisfy the contract obligation". /*
>
> *//*
>
> class base;
>
> function void f(); endfunction
>
> endclass
>
> interface class intf;
>
> pure virtual function void f();
>
> endclass
>
> virtual class der extends base implements intf;
>
> pure virtual function void f();
>
> endclass
>
> class der2 extends der;
>
> function void f(); endfuntion
>
> endclass
>
> If you have:
>
> der d = some_legal_obj;
>
> d.f();
>
> *//*
>
> */[Alsop, Thomas R] Hmmm, I think I get it. You would only do this if
> you wanted to _explicitly override the base method to be virtual_.
> This is kind of a weird case because there doesn't seem to be any
> point in using the 'implements' for this example since you are cutting
> and pasting what is in the interface class. Are we bottom line
> stating that we can do one of two things when we 'implements' an IC
> into an abstract class. We either fully define it, or we just
> cut-n-paste the prototype in so the prototype can hide the base
> implementation. And what is the decision in this case, does it hide
> the base method or do we generate an error because the base extension
> did not meet the prototype contract?/*
>
> *//*
>
> All of the above is related to a very strong paradigm requirement
> that I would like to see met. I would like to be able to say that
> adding an "implements" to any class never changes the behavior
> of that class in any way; it "obligates" the class the behave in
> some manner, but it doesn't impact the behavior of the class.
> So, assuming that the code compiles/elaborates, one can
> generalize any class based design by adding "implements"
> clauses broadly (with wild abandon) and not change any of
> the existing class behavior. Keeping that as a strong requirement
> will, I believe, lead to much more compositional code in the
> long term with much more consistent ways of reasoning about
> interactions.
>
> */[Alsop, Thomas R] I am in complete agreement with this mindset. In
> all the discussions so far I don't think I contradicted this in any
> way. But appreciate the clarity of what 'implements' should do. /*
>
> */[Tipp, Brandon P] The example is slightly flawed. The section on
> conflicts would create a method name conflict at the declaration of
> der, which would require resolution within that class. That is
> already in the proposal. The declaration within der must be virtual
> (either implicitly or explicitly depending on the answer to #17).
> Despite the fact that der2 declares f() as non-virtual, it would be
> implicitly virtual once you have the [pure] virtual declaration in
> der. The desired behavior would be that der2::f() would be called. I
> think that resolving question #17 would be sufficient for this
> proposal; and if you want to clarify the behavior of a pure virtual
> method hiding a non-pure-virtual method then that should be opened in
> a new Mantis item since it is a broad question which happens to apply
> to some of the issues that we've been discussing./*
>
GORD: I agree and that is what I said in earlier comments -- making it
clear that a virtual prototype exists resolves the issue and it is then
clear that the virtual definition at that point *hides* the earlier
non-virtual method. All the subsequent behaviors follow directly.
[...]
>
> 17) Does the user need to explicitly indicate "virtual" on the
>
> first implementing definition or is that implied by the implements
>
> in the same way as it would be during inheritance?
>
> interface class intf;
>
> pure virtual function void f();
>
> endclass
>
> class base implements intf;
>
> function void f(); endfunction
>
> endclass
>
> **
>
> *talsop> It's a contract. When you implement an interface class the
> return type, the number of arguments, and types must all match. If
> the interface class declares a method as virtual, then the
> implementing class must declare it as virtual. We should make a
> 'shall' statement on this and note that implementations will issue and
> error if the user forgets this. So my take on this is the user must
> explicitly do this and we do not have any inheriting notions here.
> Can you imagine if the implementing class did not make this virtual,
> but it was 'inherited' how hard this would be to debug when the end
> user thought he was implementing an non-virtual interface method and
> it turned out to be polymorphic?*
>
> */[Tipp, Brandon P] The interface class method must be virtual; the
> only question is if the "virtual" key word in an implementing class
> would be implicit like it is in an extending class . It sounds like
> you want it to be explicit and required, in which case something needs
> to be added to the proposal since that is not the behavior for
> inherited virtual methods. If declaring the method as virtual is
> implicit, I don't see a reason to change anything./*
>
GORD -- I would object to having "virtual" be effectively inherited.
This means that real class behavior flows from the interface class to
the interface class -- the behavior of the class hierarchy changes due
to the presence of the implements. I think that is a long-term recipe
for debugging nightmares. Imagine that you had a long inheritance
change from "base" (without the implements) and some much later
descendent defined a "f" that hid base::f but happened to be
compatible. By adding the implements you now change the behavior of any
calls based on the intervening handle types. This will potentially
lead to pretty fragile code where the fragile part is *behavior* and
arbitrarily far away from the point of the "implements". I (and others
on the committee) would much rather see a clear, local compile/elab
error regarding a missing prototype than the otherwise bizarre issues
that you'll have to debug.
Obviously just mechanically adding the prototype would introduce the
issue, but that issue can be behaviorally debugged with the single
prototype change in place; you don't have to make the problem more
involved for the end person by adding the intellectual effort of having
to think through what is going on with the implements and interface
classes. You at least have fair warning that you are explicitly
changing the behavior of a method.
If you can gather consensus for the implicit virtual application, then
we'll have to change the wording. As I've continued to say,
"implements" is not inheritance and use of that term will continue to
have me object. You cannot appeal to inheritance to define the behavior
of implements, you must define it explicitly. So unless you've already
added explicit wording saying that a class method becomes virtual in
this kind of case, I don't agree that such behavior would follow from
the proposal.
Gord
-- -------------------------------------------------------------------- Gordon Vreugdenhil 503-685-0808 Model Technology (Mentor Graphics) gordonv@model.com -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Thu Aug 11 16:47:15 2011
This archive was generated by hypermail 2.1.8 : Thu Aug 11 2011 - 16:47:19 PDT