3 July 2000  Page 1 of 5  J3/00-234

Subject: Semantics of the select kind construct are not described, and it appears to be a

mess to use

From: Van Snyder References: 98-179, 00-179, 00-186, 00-194, 00-233

1 Introduction

The select kind construct, apparently intended to be used within a derived type definition to select different specific procedures to invoke using an object of derived type, depending on the kind parameters, is not described further than providing its syntax. In particular, the relation between select kind, inheritance, and procedure overriding is not described. Furthermore, if I understand it correctly, it is quite cumbersome to use. Suppose one has a type with three kind parameters, and one anticipates three values for each of those parameters. If one procedure is needed for each combination of kind type parameter values, this results in a requirement to bind 27 procedures to the type. It appears to require 92 statements to do so, using the select kind construct: Three nested select kind constructs are needed. The inner ones needs 8 statements each – the SELECT CASE and END SELECT statements, 3 CASE statements, and 3 procedure declaration statements. Each middle one encloses three of these, and adds five more statements, for a total of 29 statements per middle level case. The outer one has three middle ones, and adds five more statements, for a total of 92 statements. The proposal here would allow to use one statement – albeit perhaps using more than one line, but not 92 lines. As I understand it, this is a very clumsy explicit replacement for the automatic generic resolution mechanism. (Actually, the intent is to specify how to generate dispatch tables, but the generic mechanism could do that more clearly.) I propose in this paper to replace the select kind construct with the already-developed generic resolution mechanism. This strategy has a simple extension to type-bound defined assignment, type-bound defined operators, type-bound derived-type input/output procedures (see 00-233), and type-bound final procedures (see 00-194).

2 Specifications

Several specific procedures may be bound to a type by using one binding name. The specific procedures bound to (not inherited into) a single type-bound procedure name shall be distinguishable according to the rules for unambiguous generic procedure reference (14.1.2.3). The PASS OBJ declaration applies to the binding name, and thereby to all of the specific procedures bound to the type, and all of its extensions, by that name, so we don’t need to worry about the case that a binding name has PASS OBJ in the parent type but not in the type being declared, or vice-versa. The rules for overriding are not much more difficult than in the case of nongeneric type-bound procedures. We don’t have an explanation for the semantics of the select kind construct, but I don’t think it would be simpler than this: If a specific procedure to be bound to a type by a particular binding name is not distinguishable from one bound to the parent by the same name, but with the type of the passed-object dummy argument replaced by the present type, by using the rules in section 14.1.2.3, it overrides the one inherited from the parent. Otherwise, it extends the set of procedures accessible by applying the generic procedure resolution mechanism to the binding name. Now consider procedure invocation. Define a type-bound generic interface for a type and binding name to be the set of procedures inherited for that binding name from the parent of the type, minus the overridden ones, plus the ones declared in the type. Each procedure in such a generic interface has a corresponding one in each generic interface for each extension type – either the same procedure or one that overrides it. First, one procedure is selected from the type-bound generic interface for the declared type of the invoking object and specified binding name, according to the generic resolution rules. Then the corresponding procedure from the type-bound generic interface for the dynamic type of the invoking object and the same binding name is invoked. From an implementors point of view, there is a separate dispatch table for each distinct generic resolution of a binding name.

3 Syntax

The proposed syntax to specify generic type-bound procedures is to specify non-generic procedure bindings by using the PROCEDURE statement, and generic bindings by using a new GENERIC statement. This has the disadvantage of requiring a new statement, and the advantage that the processor can detect one case in which one mistakenly extends the generic set instead of overriding a non-generic binding – the case when the name is already non-generic. The PROCEDURE statement is unchanged, and the proc-binding is extended to include

R440 proc-binding  is <as at present>
or GENERIC (proc-interface-name)

[, binding-attr-list] :: binding-name => NULL()

or GENERIC [, binding-attr-list] ::

binding-name => procedure-name-list

A binding-name specified in a PROCEDURE statement shall not be the same as any other binding name specified within the same derived type definition, no matter whether specified in a PROCEDURE or GENERIC statement; if it is the same as an inherited one, the present overriding rules apply – it is not permitted to extend a generic set with a PROCEDURE binding. A binding name specified in a GENERIC statement may be the same as the binding name specified in another GENERIC statement, having the same effect as if the procedurename-lists were combined in a single statement.

4 Edits

Edits refer to 00-007r1. Page and line numbers are displayed in the margin. Absent other instructions, a page and line number or line number range implies all of the indicated text is to be replaced by immediately following text, while a page and line number followed by + indicates that immediately following text is to be inserted after the indicated line. Remarks for the editor are noted in the margin, or appear between [ and ] in the text.

proc-binding 43:16-17 [ proc-binding ] ...

[Editor: Delete.] 43:19-20

R440 proc-binding  is PROCEDURE(proc-interface-name)

43:21-24

[, binding-attr-list] :: binding-name => NULL()

or PROCEDURE [[, binding-attr-list] :: ]

binding-name [=> binding]

or GENERIC(proc-interface-name)

[, binding-attr-list] :: binding-name => NULL()

or GENERIC [, binding-attr-list] ::

binding-name => binding-list

Constraint: If => binding appears, a double-colon separator shall appear before binding-name. Constraint: The binding name shall not be the same as a binding name inherited (4.5.3.2) from

the parent type for which the NON OVERRIDABLE binding attribute is specified.

Constraint: If a binding name is inherited (4.5.3.2) from the parent type, then the binding name inherited from the parent type and the one being declared shall both be declared with GENERIC or both be declared with PROCEDURE.

or NULL(procedure-name)

43:37

or NULL(procedure-pointer-name)

[Editor: Replace “procedure that has” by “procedure. The procedure-pointer-name shall be 43:39 the name of an accessible procedure pointer. The procedure or procedure pointer shall have”. After the second “procedure” insert “or procedure pointer”.]

Constraint: If NULL is specified NON OVERRIDABLE shall not be specified. 43:46-44:8 Constraint: If the binding name is the same as one inherited (4.5.3.2) from the parent type,

PASS OBJ shall be specified if and only if it is specified for the binding of the same name in the parent type.

Constraint: If PASS OBJ or NON OVERRIDABLE is specified for a generic binding name in one procedure binding within the derived type definition, it shall be specified in all procedure bindings for that binding name within the derived type definition.

Constraint: If an access-spec is specified for a generic binding name in one procedure binding within the derived type definition, and it specifies an accessibility different from the default accessibility, the same access-spec shall be specified for every GENERIC statement that specifies the same generic binding name within the derived type definition.

[Editor: Delete “-construct”.] 48:12

[Editor: Replace “said to be deferred” with “a deferred procedure binding”.] 48:26

may override (4.5.3.2) the inherited (4.5.3.1) deferred binding with another deferred binding. 48:29

[Editor: Note that 00-233 inserts a section of the same number. Put this one first.] 48:30+ 4.5.1.5.1 Generic bindings For a particular type and binding-name, a binding specified by a GENERIC statement specifies a type-bound generic interface. The set of bindings specified for that binding-name, and those that are inherited (4.5.3.1) into that type and not overridden (4.5.3.2), defines a type-bound generic interface, in exact analogy to a generic procedure name (12.3.2.1). [Editor: Insert the following unresolved issue note only if paper 00-233 also passes.] J3 internal note Unresolved issue xxx (integration) Investigate the possibility of combining this section with the following similar one about typebound derived-type input/output.

Each binding in each such type-bound generic interface has a corresponding one in the typebound generic interface for that binding-name and each extension type – either the same binding, or one that overrides it. The same binding-name may be used in several GENERIC statements within a single derived type definition. The effect is as if all of the NULL() bindings were specified by NULL(procedurepointer-name) with procedure-pointer-name specifying a procedure pointer with the same interface as the proc-interface-name, and then all the bindings were specified by a single statement.

For purposes of overriding (4.5.3.2) and generic resolution (14.1.2.3, 14.1.2.4.2\frac{1}{2}), the declared 53:22+ type of a passed-object dummy argument (4.5.1.6) of a procedure binding inherited from the parent type is considered to be the same as the type into which it is inherited.

A procedure binding declared within a derived type definition overrides one inherited from the 53:36-41 parent type if:

(1) It is declared using PROCEDURE and it has a binding name that is the same as one inherited from the parent type, or

(2) It is declared using GENERIC, it has the same binding name as one inherited from the parent type, and the specific or deferred procedure to be bound to the type by a particular binding name is not distinguishable, by using the rules in 14.1.2.3, from one inherited from the parent and bound to the same binding name.

If it is declared using GENERIC but it does not override one inherited from the parent, it extends the generic binding (4.5.1.5.1) having that binding name. If a binding overrides one inherited from the parent, it and the inherited one shall match in the following ways:

[Editor: Replace “Except ..., the” by “The”. It’s now provided by the edit at [53:22+] above.] 54:3

[Editor: Insert the following after note 4.44. Note that the same constraint is inserted by paper 54:28+ 00-233, but therein it applies to two syntax rules.] The following constraint applies to syntax rule R440: Constraint: If a procedure binding overrides one inherited from the parent type, the one inher-

ited from the parent type shall not specify the NON OVERRIDABLE attribute.

[Editor: After “)” add “or generic bindings (4.5.1.5.1)”.] 342:14

[Editor: Add a new section, after – not a subsection of – 14.1.2.4.2.] 346:22+ 14.1.2.4.2\frac{1}{2} Resolving generic type bound procedure references If a generic type-bound procedure binding is specified by data-ref % binding-name in a function reference or call statement:

(1) If the reference is consistent with one of the specific interfaces in the generic binding (4.5.1.5.1) for the binding-name and the declared type of the data-ref, that interface is selected.

(2) Otherwise, if the reference is consistent with an elemental reference to one of the specific interfaces in the generic binding (4.5.1.5.1) for the binding-name and the declared type of the data-ref, that interface is selected.

(3) If an interface is selected by (1) or (2) above, the reference is to the specific binding that provides the interface in the generic binding for the binding-name and the dynamic type of the data-ref that corresponds to the selected interface.

If no interface is selected in (1) or (2), or the reference determined in (3) is to a deferred binding (4.5.1.5), an error condition occurs.

deferred procedure binding (4.5.1.5): a type-bound procedure binding that specifies the 400:17+ NULL() intrinsic. A deferred procedure binding shall not be invoked.