[sv-bc] Re: Resolution of inherited type names

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Mon Sep 10 2007 - 11:45:52 PDT
Mark,

You are actually not reproducing my suggested approach
correctly.

I was suggesting:

       module child #(type T = int);
         int T2;
         class C extends T;

EITHER
            typedef T::T2 T2;     // alternative 1
OR
            typedef super.T2 T2;  // alternative 2

         endclass
       endmodule


This is essentially the same form as what is currently
used for interface types and exposes the type
assumption directly in exactly the same manner as
with interface types.


But the other aspect is that you are agreeing (I think)
that some special form is needed for knowledge about
types.


So why not just normalize the whole thing and require
the same behavior in all cases of opaque inheritance?
That allows for a clean long term design using
explicit specifications (or short term if people want
to spin this out immediately).


Here is a more complete example of what I've suggested
a few times now (similar to Java interfaces).

    specification C;
        type T2;
        function T2 f(T2);
        T2 x;
    endspecification

    module m #(type T = int implements C);
       class D extends T;
          T2 foo;
       endclass
    endmodule


The "implements C" doesn't express an object "is a"
relationship but rather a "has a" relationship.  It
means that anything that implements specification
C must provide a type named "T2", etc.  This can
then directly be used in many scenarios, including
not only classes but potentially also interface type
references and makes all the type assumptions explicit
and locally determinable.

If you couple this with Brad's suggestion that "no default"
means "must provide an override" you get really nice
looking designs:

    module m #(type T implements C);

means "T must be overridden but must provide the names
defined by the specification C".


    module m #(type T = D implements C);

means "T may be overridden but BOTH an override
and the type "D" must provide the names defined by
the specification C".



I think that going to such an explicit form would make
all of the issues go away and would be a very extensible
long term solution.


Gord.



Mark Hartoog wrote:
> There are two issues with your example. One is that
> it is generally assumed that type names are known at 
> parse time. The use of the type operator solves that
> problem in cases where the type name may not be known 
> at parse time. In your example, if you wrote: 
> 
>       module child #(type T = int);
>         int T2;
>         class C extends T;
>            T::T2 x;
>         endclass
>       endmodule
> 
> You still would not know at parse time if T::T2 was a 
> type name, although you would know that 'T2' was suppose
> to resolve in the type 'T'. I think in this case you would
> still need the type operator to make it clear at parse
> time that 'T::T2' was a type. 
> 
> Now the type operator has the side effect of converting 
> a variable reference into a type. If you find that extremely 
> objectionable, then it would require some new keyword like
> C++ to specify that 'T::T2' has to turn out to be a type.
> I was simply trying to avoid adding anymore new keywords
> to the language to handle this corner case. 
> 
> 
>> -----Original Message-----
>> From: Gordon Vreugdenhil [mailto:gordonv@model.com] 
>> Sent: Monday, September 10, 2007 10:12 AM
>> To: Mark Hartoog
>> Cc: SV_EC List; SV_BC List
>> Subject: Re: Resolution of inherited type names
>>
>> Mark,
>>
>> First of all, "type T" in C++ is rather different in that it 
>> is a specification that T denotes a type, it is NOT an 
>> operator as such.  In your example, I am assuming that you 
>> want "type(T2)"
>> to *conditionally* bind to T::T2 or type(int) depending on 
>> whether T2 exists in T or not.  That is not at all what C++ 
>> does.  In C++, "type T"
>> means "treat the token T as a type" and is only needed once 
>> in a context to deal with parsing ambiguities.  In your 
>> approach you would need to use "type(T2)" on each occurrence 
>> of T2 since "type" is an operator in SV and it is being used 
>> not to indicate a static constraint (that T2 is a type) but 
>> rather as a magic "defer the name lookup" operation.  T2 
>> could still bind to either a type or a variable.
>>
>> You didn't address what a bare "T2" means -- is it illegal?  
>> Does it mean the T2 in child?
>>
>> You've also argued that the special resolution only occurs in 
>> methods.  How do you align that with your example here?  And 
>> if you generalize your rules, how are you going to address 
>> all the other problematic cases that I raised earlier?  
>> Finally, types now appear to be completely different in your 
>> approach -- you need some sort of explicit indication for 
>> those but not for other things.
>>
>> Gord.
>>
>>
>> Mark Hartoog wrote:
>>> In C++ they introduced the typename keyword for cases were it was 
>>> ambiguous if something was a type or not at parse time:
>>>
>>> template <class T>
>>>    class foo {
>>>       typename T::T2 x;
>>>    };
>>>
>>> The 'typename' keyword indicates that 'T::T2' must be a type.
>>>
>>> In System Verilog we do not need any new keywords, since we already 
>>> have the type operator for these cases:
>>>
>>>      module child #(type T = int);
>>>        int T2;
>>>        class C extends T;
>>>           type(T2) x;
>>>        endclass
>>>      endmodule
>>>
>>>> -----Original Message-----
>>>> From: Gordon Vreugdenhil [mailto:gordonv@model.com]
>>>> Sent: Friday, September 07, 2007 3:12 PM
>>>> To: SV_EC List; Mark Hartoog; SV_BC List
>>>> Subject: Resolution of inherited type names
>>>>
>>>> Mark, I think I raised this once a long time ago but I'll raise it 
>>>> again since I think we've both neglected to discuss this scenario.
>>>>
>>>> Given your rules, I don't think you can have symmetric handling of 
>>>> type names versus member/property names when inheriting from an 
>>>> opaque type.  Specifically, what rules would you apply 
>> when dealing 
>>>> with something like the following:
>>>>     module child #(type T = int);
>>>>       int T2;
>>>>       class C extends T;
>>>>          T2 x;
>>>>       endclass
>>>>     endmodule
>>>>
>>>> In order to be consistent with your approach elsewhere, would you 
>>>> have to assume that "T2" is an inherited type and defer all of the 
>>>> handling until elaboration?  Is that even possible to parse in 
>>>> general if you don't know whether T2 denotes a type or a variable?
>>>>
>>>> I suspect that for inherited types in such a situation you 
>> would have 
>>>> to adopt an approach similar to mine, would you not?
>>>>
>>>> My suggested approach to solving such a scenario is 
>> similar to what I 
>>>> want to do in every case; require explicit referencing.  Here, I'd 
>>>> either be willing to allow something like "typedef T::T2 T2;"  or 
>>>> "typedef super.T2 T2" to directly declare that "T2" is an 
>> inherited 
>>>> type.  In the long term, as I've suggested before, I'd like a more 
>>>> complete "specification" for "T" that would directly give the 
>>>> assumptions about what T provides rather than working from 
>> indirect 
>>>> information in the body of C.
>>>>
>>>> Gord.
>>>> --
>>>>
>> --------------------------------------------------------------------
>>>> Gordon Vreugdenhil                                503-685-0808
>>>> Model Technology (Mentor Graphics)                gordonv@model.com
>>>>
>>>>
>> --
>> --------------------------------------------------------------------
>> Gordon Vreugdenhil                                503-685-0808
>> Model Technology (Mentor Graphics)                gordonv@model.com
>>
>>

-- 
--------------------------------------------------------------------
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 Mon Sep 10 11:46:16 2007

This archive was generated by hypermail 2.1.8 : Mon Sep 10 2007 - 11:46:25 PDT