[sv-ec] RE: Last major issues on interface classes - 1356 review

From: Alsop, Thomas R <thomas.r.alsop@intel.com>
Date: Tue Aug 02 2011 - 10:52:27 PDT

From: Gordon Vreugdenhil [mailto:gordonv@model.com]
Sent: Monday, August 01, 2011 4:33 PM
To: Alsop, Thomas R
Cc: SV_EC List; Tipp, Brandon P
Subject: Re: Last major issues on interface classes - 1356 review

Tom,

I owe a summary of committee discussion on my list to the
reflector; I'll do that either late tonight or tomorrow but let
me respond to 16-18 right away.

I don't agree with your suggestions on 16; I definitely do not
want to open the door in any way to extending interfaces into
a class. That both defeats the orthogonality of the intent of
"extends" (i.e. a class could not then extend a concrete base
and implement an interface) and would re-introduce very
problematic questions about visibility through inheritance.
[Alsop, Thomas R] I thought it actually clearly delineated extends (allows inheritance) from implements (which forces contractual obligations). But I just re-read the abstract clause in the LRM and I can see where this really gets out of hand with abstract classes being extended from non-abstract classes. So let's just stick with 'implements' for interface classes (IC) (with the exception of extending from another IC)

There was agreement in discussion that my example in
16 as written should not be legal. A virtual class must
define a prototype (or inherit one from another class)
for each implemented class method. That makes the
contract point clear and provides a clear (forward) obligation
to any non-virtual class extending the virtual class.
[Alsop, Thomas R] Okay, so what is the point then in 'implementing' from an IC in an abstract class? In my mind the abstract class can either prototype or fully define a method. If an abstract class is using 'implements' it should be forced via the contract to fully define the method. The only prototypes that should be there are those that are extended/inherited from another abstract class or those that are being prototyped by the abstract class (not from a contract). I don't understand what you mean by a virtual class must define a prototype... for each implemented class method?? This seems like we are just cut and pasting the prototype method from the IC.

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.

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.

Gord.

On 8/1/2011 4:02 PM, Alsop, Thomas R wrote:
Gord, I'm only responding to questions 16-18 for now. All the others, I'll get to tomorrow as they are less critical. Let's bottom out on this first and then tackle the minor issues left.

-Tom

16) Can a handle to an abstract base class be used as a reference
    to an implemented method even if the method is not directly
    declared? So is the following legal:

        interface class intf;
            pure virtual function void f();
        endclass
        virtual class base implements intf;
        endclass
           //...
        base b = some_valid_object_derived_from_base;
        b.f(); // <<<< is this legal?

    It is not clear from the proposal that this is legal although
    my expectation from committee discusion is that people would
    like it to be.

    We should carefully consider that choice. Allowing
    "base" to essentially inherit the pure function prototype
    weakens the distinction between "extends" and "implements"
    and also may pose later surprises if "base" doesn't
    implement everything. By requiring "base" to have all
    needed prototypes, one gets a clear picture at the point
    of the implements of what obligations may still be outstanding
    in the type hierarchy derived from base. So I'd prefer to
    require "base" to prototype all implemented methods or,
    at least, to disallow calls from "base" to an unprototyped
    implemented method.
talsop> I agree that we should require the base to fulfill the implements contract and prototype the methods. This is the meaning behind 'implements'. I think the act of inheriting methods from the parents should come from the 'extends' construct. This keeps the rules crystal clear on usage of the two constructs. That said, for abstract classes, I can see people wanting to 'inherit' interface class methods or in other words, inherit the contract so that the abstract class carries with it now the contract thereby requiring child classes to prototype the method. If we really want this why don't we just allow an abstract class to 'extend' an interface class or multiple interface classes? Then the above implementation becomes:

        interface class intf;
            pure virtual function void f();
        endclass
        virtual class base extends intf;
        endclass
           //...
        base b = some_valid_object_derived_from_base;
        b.f(); // <<<< This would then be legal

This makes a clear distinction between the abilities that we give the 'implements' vs 'extends'. We can state in the LRM that abstract/virtual classes may either 'extend' an interface class (in which case they inherit the contract for child extensions) or 'implement' them which would force the abstract class to provide the prototypes. This clarifies where in the parent/child hierarchy who is inheriting vs who is really implementing. Currently the proposal does not allow abstract classes to extend an interface class, but we can change this.

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?

18) The question of whether a pure virtual hides a non-virtual is
    still open. So is the following legal:
        class base;
            function void f(); endfunction
        endclass
        interface class intf;
            pure virtual function void f();
        endclass
        virtual class der extends base implements intf;
        endclass
        class der2 extends der;
            function void f(); endfuntion
        endclass
    If you have:
        der d = some_legal_obj;
        d.f();
    what is called?

talsop> Going back to my answer on Q16, this become clear. The 'der' class above, even though it's abstract, would still be required to prototype the intf class, however, since the prototype was additionally extended from base, the prototype requirement is met. So while it is declared as a virtual class, in this case it would be fully prototyped. The only reason to declare 'der' as virtual would be to include other pure functions.

-----Original Message-----
From: owner-sv-ec@eda.org<mailto:owner-sv-ec@eda.org> [mailto:owner-sv-ec@eda.org] On Behalf Of Gordon Vreugdenhil
Sent: Monday, August 01, 2011 8:55 AM
To: SV_EC List
Subject: [sv-ec] Additional 1356 review (interface classes)

Since I haven't seen any other review of 1356 since the ver7 upload, I went ahead and did another fairly deep review. Attached are my review comments.

Gord.

--
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com<mailto:gordonv@model.com>
--
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com<mailto:gordonv@model.com>
-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Tue Aug 2 10:53:26 2011

This archive was generated by hypermail 2.1.8 : Tue Aug 02 2011 - 10:53:37 PDT