[sv-ec] Mantis 1857 rationale - extern method types for parameterized classes

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Mon Jun 18 2007 - 07:24:49 PDT
Here is an example of the issue that Mantis 1857 is addressing:

    typedef bit T;

    class C #(type T = int);
       T x;
       extern function T get();
    endclass


Currently, I have two synatactic alternatives when
defining the body of "get":

1)  function T C::get();
2)  function C::T C::get();

Both of these have problems for this case.  What the
compiler must do is associate "T" with the unspecialized
name "T" in class C; that is, "T" behaves exactly the same
as if the method were defined inside the parameterized class
and required a specialization.  It is not correct to associate
"T" with any definite type.


In the first case, the name "T" is visible in the scope
of the definition (i.e. the "typedef bit T") so that is
the "T" that will be selected.  Clearly that is incorrect.


The second case is a bit more subtle.  The reference "C::T"
is a *type reference* and the LRM says that any *reference*
to "C" means  the default specialization of C.  So now we can
consider a non-member function:

    function C::T someother_function();
    endfunction

"someother_function" is not a member, therefore C::T must
denote an actual definite type.  In this case it MUST
be the "T" in the default specialization of "C".


So right now there is a definite ambiguity.  One might attempt
to solve the ambiguity be requiring lookahead to see if the
function is of the form "C::", but the amount of lookahead
is unbounded since the return type could be arbitrarily
complex.

Given the ambiguity, something must be done in the language to
deal with how to express both an extern and a non-member
function in terms of referring correctly to "T".

We could deprecate the "C::" syntax for referring to a default
specialization, but there is already a great deal of code
around that uses that -- "mailbox m;" is such a default
specialization of "mailbox".  So I don't think I'd want to
go that route.

We could require C#()::T for a function return type if the return
type was intended to denote a specialization, but that would mean
that there was a context in which there were different rules for
specialization.  I really don't like that -- users already struggle
with this to some extent.

So, the suggestion is to allow the new syntax:
    C::function T get();

This has a pretty natural reading, is unambiguous, and is
in fact easier to see the "identical" nature of the extern
declaration in the class and the definition (cut-and-paste
and replace "extern" with "class_name ::".

To allow for backwards compatibility, the old form is permitted
with the recognition that the new form is the only way to
correctly express the types in a scenario such as the one
I described above.


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 Mon Jun 18 07:25:08 2007

This archive was generated by hypermail 2.1.8 : Mon Jun 18 2007 - 07:25:23 PDT