From jls@liverpool.ac.uk Mon Oct  4 15:58:26 1993
Received: from ns.dknet.dk by dkuug.dk with SMTP id AB26989
  (5.65c8/IDA-1.4.4j for <SC22WG5@dkuug.dk>); Mon, 4 Oct 1993 14:38:47 +0100
Received: from mail.liv.ac.uk by ns.dknet.dk with SMTP id AA19553
  (5.65c8/IDA-1.4.4j for <SC22WG5@dkuug.dk>); Mon, 4 Oct 1993 12:24:40 +0100
Received: from liverpool.ac.uk by mailhub.liverpool.ac.uk with SMTP (PP) 
          id <06406-0@mailhub.liverpool.ac.uk>; Mon, 4 Oct 1993 12:20:11 +0100
From: "Dr.J.L.Schonfelder" <jls@liverpool.ac.uk>
Message-Id: <9310041120.AA16193@uxh.liv.ac.uk>
Subject: Derived Type parameters
To: SC22WG5@dkuug.dk (SC22/WG5 members)
Date: Mon, 4 Oct 93 12:20:09 BST
X-Mailer: ELM [version 2.3 PL11]
X-Charset: ASCII
X-Char-Esc: 29

Here is a paper on the above topic as promised. I hope X3j3
will look at this at its next meeting. I will forward a
printed copy to David as well.
Regards
Lawrie
===================================================================
                                                              JLS-1
To: X3J3 and WG5
From: Lawrie Schonfelder (on behalf of the UK panel IST/5/-/5)
 
                     Parameterised Derived Types

1 Introduction  
There is substantial need for the regularisation of Fortran to allow
all types both intrinsic and derived to be parameterised.  The lack
of parameterised derived types greatly restricts their use in
contexts where they are required to interwork with parameterised
intrinsic types.  As a result of this WG5 requested that proposals
to include this functionality be considered for the 95 revision of
the language. X3J3 asked the UK, in particular JLS, to prepare an
initial paper describing possible approaches to the issue.  
    Three proposals are described below.  These are in decreasing
size of addition and with correspondingly decreasing functionality. 
The first attempts to provide a full flexibility coverage of the
functionality allowing for both KIND and non-KIND parameters and any
number of either to be employed.  The second simplifies this general
approach by restriction the number of KIND parameters permitted.  The
final minimum proposal, which nevertheless provides for the most
critical requirement, retains only the single KIND parameter.  The
proposals have been developed and presented in this way so as to show
how the reduced functionality proposals leave open the possibility
of subsequent extension to provide the more complete facility.
    The proposals are tutorial in nature. They are given as exemplars
of the sort of syntax and semantics that could be added to the
existing Fortran 90 language to provide the required functionality.

2 Full Facility Proposal    
The intrinsic types have two quite different parameters.  There are
the static parameters that determine the nature of the machine
representation. These are all characterised by all types having the
same keyword, KIND, for such a parameter.  The other parameter type
where the value is not necessarily static, only applies for the
character type.  Here the parameter, LEN, determines the length or
the number of characters in the datum.  A full parameterised data
type proposal must allow for any number of both sorts of parameter
for user defined types.
    The general approach to the problem, as was part of the F8x
proposals (see S8-104), is to allow the user to specify a set of
dummy parameters as part of a derived type definition. These
parameters are then used within the definition as primaries in
specification expressions determining array bounds and character
lengths, etc., for components.  Actual values must be supplied when
objects of the type are declared or constructed.  For example, we
might define a type MATRIX with a parameter to determine its
dimensionality,

TYPE MATRIX(dim)
  REAL,DIMENSION(dim,dim) :: element
ENDTYPE MATRIX

objects of this type could then be declared,

type(MATRIX(3)) :: rotate,trans
type(MATRIX(4)) :: metric
type(MATRIX(dim=n)) :: weight

where this last would be declaring an automatic or dummy object, c.f.
similar usage with the length parameter with characters. For dummy
arguments this style of parameter could also be specified as assumed;
this would be indicated as for character by an asterisk, and would
mean that the value would be assumed from that for the actual
argument.
    The handling from a descriptional point of view such LEN-style
parameters is quite straight forward.  There are more significant
complications when KIND-style parameters are required.  Basically,
if a parameter is used within a type definition to determine the kind
of a component type then as for intrinsic types the actual values of
such parameters must be static and hence are restricted to being
determined by initialisation expressions.  If in the above example
we wanted to have a general matrix type which had user selected
component kind as well as user specified dimensionality we might wish
to have a type,

TYPE MATRIX(kind,dim)
  REAL(kind),DIMENSION(dim,dim) :: element
ENDTYPE MATRIX

and declarations of the form,

type(MATRIX(4,3)) :: rotate,trans
type(MATRIX(8,4)) :: metric
type(MATRIX(kind=4,dim=n)) :: weight

where now although the dim parameter may be given by a specification
expression or *, the kind parameter must be an initialisation
expression. As with character a difference in kind style values would
be able to resolve overloads but those of length style ones would
not.
    Semantically the distinction between which parameters are kind-
style and which are not is easy.  Any parameter which ultimately is
used to determine the kind of a component must be a kind-style
parameter.  The question is how should this distinction be indicated
syntactically so that the nature of a given parameter is always clear
at compile time.  For the intrinsic types this has been done by
always using the keyword KIND for such parameters.  However, for a
general derived type which may have arbitrarily complex component
structures there may be the need for independent kind-style
parameterisation for many different components of different type. 
We need to have the possibility of multiple kind-style parameters for
a single type.  A suggested possible syntactic device for handling
this would be to require all kind-style parameters to have names that
start with "KIND", and forbid any non kind-style parameter having a
name starting with "KIND".  This would allow a type such as

TYPE WEIRD(kind_c,kind_r,kind_i,maxlen)
  CHARACTER(KIND=kind_c,LEN=maxlen) :: desc
  REAL(KIND=kind_r) :: x,y,z
  INTEGER(KIND=kind_i) :: id
ENDTYPE WEIRD

to be written.  The declaration of an object of this type would then
look like,

type(WEIRD(1,8,2,20)) :: funset(100)

This would create an array of 100 objects of type WEIRD each of which
had a character component of length 20 and kind 1, three real
components each of kind 8, and an integer component of kind 2. 
    A further major semantic distinction between kind-style and non
kind-style parameters is in their use with procedure arguments. 
Again as with intrinsic types, kind parameter values for arguments
may resolve overloads but non kind parameter values cannot since they
are not necessarily static.
    As for the intrinsic types each parameter must have associated
with it an intrinsic inquiry function with a generic name that is
that of the parameter.  Such functions would take as their single
argument any object of the type having the parameter and would return
the current value for that parameter.  The defining of a
parameterised type creates implicitly an inquiry function for every
parameter.  Thus for the types defined above there would be functions
for each of the parameters defined and the following calls would
yield the indicated results.

kind(metric) = 8
dim(metric) = 4
kind_i(funset(1)) = 2
maxlen(funset) = 20

The least obvious extension is in how should the syntax of the value
constructor be extended.  One approach that could be used would be
to extend the analogy with the REAL type conversion function and the
type value constructor which also behaves syntactically like a
function reference and acts essentially as a type converter.  In this
case the extended for of the constructor reference would be to
include the parameters as an extra set of arguments following the
list of component expressions.  The analogy with

REAL(A,KIND)

for  the matrix type would be

MATRIX(element,kind,dim)

Another approach would be simply to extend the constructor syntax
with the type-name now having if necessary an attached list of
parameters,

MATRIX(kind,dim)(element)

The semantics in each case would be the same.  The element would have
to be a rank 2 array of reals with dimensions that matched those
specified by dim.  The assignment coercion would apply so as to
ensure that regardless of the kind of the array the kind of the value
produced would be as specified by the parameter.  (My preference
would be to adopt the former approach as this is more regular and
more extensible; it does not require a new and rather odd syntactic
entity of  concatenated parenthetical lists. )
    The major document changes associated with this proposal would be
in sections 4.4, 5.1, 7.1, 7.5, 12.2, 12.3, 12.4,  & 13 (if the first
of the two options above is adopted). This is probably not an
exhaustive list of sections affected.  A grep on type-parameter and
derived type would help locate additional areas that might be
involved.

3 Intermediate Proposal     
The intermediate proposal is to follow essentially the design set out
above but to restrict the number of kind-style in any type to one
only to be called KIND.  This reduces the complexity of description
and implementation at the expense of making some types virtually
impossible to define. However, the availability of the single kind
parameter allows the vast majority of currently envisaged useful
types to be constructed quite straight forwardly. The bulk of these
depend on collections of components of a single intrinsic type,
normally real, all of which are required to be of the same but
specified kind .  The non kind-style parameters would be handled as
above.
    This proposal would effect much the same sections of the
document. The task of editorially implementing this extension would
be reduced but not by a dramatic amount.  The implementation
reduction would be rather more significant.

4 Minimum Proposal  
This minimum proposal only extends to the point of allowing a single
kind-style parameter to be included in the definition.  This clearly
does not allow the arbitrary dimension matrix type or any of the
other types with specified array bound and/or character length
components.  It does however allow the immediate pressing need for
specified kind in derived types.  It has the substantial simplifying
property of not introducing any new generic intrinsic procedure
names.  It merely adds overloads to the existing KIND function.
    In descriptional terms the simplification is likely to be
significant although most of the sections indicated above would
require text changes but the changes in section 13 would be
relatively very much reduced.  The implementation of this minimum
proposal would be very much simplified.
(My personal view on the choices is that I would strongly support
either of the first two options.  I think the minimum proposal
restriction to just the single KIND parameter is so limited in
functionality as to hardly justify the work involved. The extra work
to do the more complete job would not in my opinion delay the
standard significantly)

5 Edits to 1539 : 1991  
The following are a first attempt at providing edits to the current
document to implement the above functionality. The edits are aimed
at implementing the intermediate proposal. The UK panel believes this
is the right level to aim at doing for F95. It has a reasonable cost
for implementation in the edits to the standard and would not be too
difficult to add to F90 processors. 
    Note, where new syntax rules are inserted they are numbered with
a decimal addition to the rule number that preceeds them. In the
actual document these will have to be properly numbered in the
revised sequence.

5.1 2.4.1.2     [13/22]
    before "agreement" add "and type parameter"

5.2 4   [25/14]
    replace "Intrinsic data-types are" by "Data types may be"

5.3 4.4.1   [33/3]
    Add to end of R424 "[(type-param-name-list)]"

    Add new rule
R424.1  type-param-name      is     KIND
                     or     kind
                     or     non-kind-type-param-name"

    Add constraints
Constraint:     A non-kind-type-param-name must not start with the
                characters KIND or kind.

Constraint:     At most one parameter named KIND may be specified on
                any derived-type-stmt.
Constraint:     If the derived-type-stmt specifies type parameters,
                SEQUENCE must not be present.

5.4 4.4.1   [33/26]
    Add constraints
Constraint:     If the type-spec specifies a value for a kind type
                parameter, this must be a scalar integer
                initialisation expression, or a scalar initialisation
                expression  involving as a primary the type parameter
                name KIND, provided this parameter name was specified
                as a type-parameter-name on the derived-type-stmt.
Constraint:     If the type-spec specifies a value for a nonkind type
                parameter, this must be a scalar integer constant
                expression, or a scalar integer constant expression
                involving as primaries nonkind type parameter names
                provided each of these names were specified as a
                type-parameter-name on the derived-type-stmt.

5.5 4.4.1   [33/37]
    Add at end of line "or a constant expression involving as
primaries nonkind type parameter names provided each of these names
were specified as a type-parameter-name on the derived-type-stmt."

5.6 4.4.1   [33/38]
    Add following paragraph
If the type is defined with type parameters actual values for these
must be defined when an entity of this type is declared or
constructed. These values may be used via the associated type
parameter names to specify character lengths, array bounds, kinds or
other type parameter values for components of the type.

5.7 4.4.1   [34/34]
    Add following paragraph
Examples of type-definitions with type parameters are:

TYPE VECTOR(KIND, ORDER)
  REAL(KIND) :: comp(1:ORDER)
ENDTYPE VECTOR

Objects of type VECTOR could be declared:

TYPE(VECTOR(4,3)) :: rotation
TYPE(VECTOR(8,100)) :: steepest

The scalar variable rotation is a three-vector with each component
represented by a kind=4 real. The scalar vector steepest is vector
in a 100 dimension space and each component is represented by a
kind=8 real.

For each type parameter specified there is a generic intrinsic
inquiry function that is created and defined implicitly by the type
definition (13.?.?). This function has the type parameter name as its
generic name it takes as its argument any entity of the derived type,
and it returns as its result the integer value for this parameter
that applies for its argument, for example, KIND(rotation) would
return 4 and ORDER(steepest)would return 100.

5.8 4.4.4   [37/3]
    Replace "value of" by "value of the"

5.9 4.4.4   [37/5]
    Replace "expr-list" by "expr-list[,type-param-expr-list]"
    Add constraint
Constraint:     If the derived type definition referenced by type-
                name specifies one or more type parameters, the type-
                param-expr-list must be present and not otherwise.

5.10 4.4.4  [37/10]
    Before "A structure" add
The type parameter expressions, if present, provide values for the
type parameters specified for the type and hence control the possible
kinds, lengths, shapes and type parameters of the components.

5.11 4.4.4  [37/16]
    Add the following paragraph
An example of a constructor for a parameterised type is:

VECTOR(0.0,8,3)

This would construct a three-vector whose components were all zero
and of kind=8 real.

5.12 5.1    [39/24]
    Replace "type-name" by "type-name[type-selector]"

5.13 5.1    [39/39]
    Add constraint
Constraint:     The type-selector must appear if the type is
                parameterised and must not appear otherwise.

5.14 5.1.1.7    [43/23]
    Add rules and constraints
R509.1  type-selector   is      (type-param-selector-list)

R509.2  type-param-selector     is      [type-param-name=]type-param-
expr

R509.3  type-param-expr      is     scalar-int-initialisation-expr
                     or     type-param-value

Constraint:     There must be one and only one type-param-selector
                corresponding to each type parameter specified for
                the type in its type definition.

Constraint:     The type-param-expr must be a scalar-int-
                initialisation-expr if the corresponding type
                parameter is a kind type parameter.

Constraint:     The type-param-name= may be omitted from the list if
                it was omitted from all previous type-param-selector
                in the list.

The type selector, if present, specifies the values to be used for
the type parameters of the type and hence the values to be used to
determine the specified properties of the dependent components of the
type.

{{{{The rules associated with type-param-values, in particular
automatic and assumed type parameters, appear to be covered in the
description for character length. A reordering of this material might
read better but I think the current text is actually correct even
though it now has extended effect.}}}}

5.15 7.1.4.2    [76/29]
    After "parameter." add "A derived type expression has a kind type
parameter and nonkind type parameters if these are specified for the
type by its type definition."

5.16 7.1.4.2    [76/48]
    Add
"The type parameters of a derived type expression, if any, are
determined by the function defining the operation."

5.17 7.1.7      [80/29]
    Add paragraph
The appearance of a structure constructor requires the evaluation of
the component expressions and may require the evaluation of type
parameter expressions. The type of an expression in which a structure
constructor appears does not affect, and is not effected by, the
evaluation of such expressions, except that evaluation of the kind
type parameter may affect the resolution of a generic reference to
a defined operation or function and hence may affect the expression
type.

5.18 7.5.1.2    [89/28]
    Replace "type," by "type and the same type parameter values,"

5.19 7.5.1.4    [90/36]
    Add paragraph
For a derived type intrinsic assignment statement, variable and expr
must have the same type and must have the same values for all type
parameters if these are specified for the type.

5.20 12.2.1.1   [166/6]
    Replace "or character length" by " character length, or nonkind
type parameter"

5.21 12.3.1.1   [167/2]
    Replace "that" by "that assumes the value for a nonkind derived
type parameter or that"
 
5.22 12.3.1.1   [167/4]
    Add additional item to list and renumber list
    (e)     A result with a nonconstant type parameter value (derived
            type functions only)

5.23 12.4.1.1   [172/41]
    Add sentance
The nonkind type parameters of the actual argument must agree with
those of the dummy argument.

5.24 13.5.5     [184/22-23]
    Delete "or" Add to end of sentance ", or a derived type for which
a kind type parameter is specified"

5.25 13.5       [184/27+]
    Add new section 13.5.6 and renumber subsequent sections as
required
13.5.6  Derived Type Inquiry functions
For each type parameter specified in a derived type definition
(4.4.1) there is an inquiry function of the parameter name taking an
object of the relevant type as its argument that returns the value
of the named parameter. The value of the argument need not be
defined. It is not necessary for the processor to evaluate the
argument of this function if the value of the function can be
determined otherwise.
For example, given a type defined as

TYPE MATRIX(KIND,ORDER)
  REAL(KIND),DIMENSION(ORDER,ORDER)
ENDTYPE MATRIX

and the object declaration

TYPE(MATRIX(KIND=4,ORDER=9)) :: weight

the derived type inquiry function

ORDER(weight)

would return the integer value 9.

5.26 13.13.51   [214/5]
    Add before the end of sentance "or any derived type with a
specified kind type parameter"

5.27 14.1.2     [241/26]
    Replace ", in" by " and type parameters, in"

6 Proposal  
That facilities for parameterising derived types along the lines
outlined above in the "Intermediate proposal" discussion be added to
Fortran at the 1995 revision.
=================================
-- 
Dr.J.L.Schonfelder
Director, Computing Services Dept.
University of Liverpool, UK
Phone: +44(51)794 3716
FAX  : +44(51)794 3759
email: jls@liv.ac.uk   

