-
Notifications
You must be signed in to change notification settings - Fork 8
/
Generics_Requirements.txt
242 lines (171 loc) · 7.56 KB
/
Generics_Requirements.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
To: J3 J3/##-###
From: Tom Clune & generics subgroup
Subject: Generics formal requirements
Date: 2022-January-02
Reference: 21-187, 21-144r4
1. Introduction
===============
At meeting 224, generics subgroup introduced a use cases paper that
was sufficient to drive solutions that would accommodate a broader set
of use cases that were endorsed by subgroup.
Here we present the formal requirements that have been derived from
these use cases.
2. Formal requirements
======================
A. Named templates shall be provided.
Notionally templates will be much like modules --
containing specification and implementation sections. But these will
be distinct from modules. A suggestive example is as follows
TEMPLATE TMPL(U)
TYPE :: U
END TYPE
CONTAINS
PURE FUNCTION GET_ITH(arr, i) result(ith)
TYPE(U) :: ith
TYPE(U), INTENT(IN) :: arr(:)
INTEGER, INTENT(IN) :: i
ith = arr(i)
END FUNCTION
END TEMPLATE TMPL
Rationale 1: Having a separate construct will allow templates to
be defined _and_ instantiated within the same scope.
Rationale 2: This approach sidesteps thorny issues with
submodules that would be introduced with a parameterized
module approach.
B. Named restrictions shall be provided.
Notionally, a "restriction" is a construct which specifies
operations that must be supported for legal instantiations of a
template. E.g., we may require that types T and U can be added
to produce objects of type V. A very hand-wavy syntax could be
something like:
RESTRICTION :: BINARYOP(+,T,U,V)
TYPE T; END TYPE
TYPE U; END TYPE
TYPE V; END TYPE
T + U => V
END RESTRICTION
C1. A template shall have zero or more dummy template parameters.
Note: A zero parameter template would be very similar to a
plain module. But the additional scoping might make
this useful?
C2. A template can define any of the following entities:
- derived type
- variable
- procedure
- interface
D. A template dummy parameter must be one of the following:
- type name
- value
- procedure
- operator
A suggestive example involving all categories of dummy template
parameters:
TEMPLATE TMPL2(T,C,sub,+)
TYPE :: T
END TYPE
INTEGER :: C
INTERFACE
SUBROUTINE sub(x)
TYPE(T), INTENT(INOUT) :: x
END SUBROTUINE sub
END INTERFACE
END TEMPLATE
Note: Operators may not require explicit declaration as both
intrinsic and user-defined operators are self-evident by
their syntax.
E. A template shall be instantiated by specifying an actual parameter
for each dummy template parameter.
E1. A type-spec must be provided for a type name dummy template parameter.
E2. A const-expr must be provided for a value dummy template parameter.
E3. A procedure or a generic-spec must be provided for a
procedure dummy template parameter
E4. An operator must be provided for an operator dummy template parameter.
Notional syntax:
INSTANTIATE TMPL(INTEGER(KIND=INT32))
...
INTEGER(KIND=INT32) :: I, ARRAY(10)
...
I = GET_ITH(ARRAY, 3)
Note 1: A generic-spec may be passed as a dummy argument, because resolution can be
done during instantiation.
Note 2: A generic operator may be passed as a dummy argument, because resolution can
be done during instantiation.
Rationale: Client code often does not have access to specific
names for procedures and operators. And the ability
to use generic entities is too important too disallow
in this context. In particular intrinsic operators
are extremely important.
F. Multiple instantiations of a given template with identical actual
template parameters define the same entities.
Note that this is somewhat contrary to the existing situation
where two otherwise identical derived types define distinct
types.
G. A named restriction shall have a set of zero or more dummy restriction
parameters.
NOTE: The zero-argument case here is not useful. Possibly this
should become "one or more".
H. An dummy restriction parameter shall be one of the same categories
as for dummy template parameters. (type, value, procedure, operator)
Note: "value" probably does not make sense in this context. But
possibly does no harm?
I. A named restrictions shall specify a set of "relations".
J. A restriction relation specifies one of the following:
- an operator and the types of its operands and result
- a procedure and the types of its arguments; in the case of
a function it must also specify the type of the result
K. A template may impose zero or more "requires".
A suggestive example with 2 REQUIRES
RESTRICTION :: MAGMA(U, OPERATOR(+))
TYPE :: U
END TYPE :: U
U + U => U
END RESTRICTION
TEMPLATE :: TMPL2(U, V)
REQUIRES MAGMA(U, OPERATOR(+))
REQUIRES MAGMA(V, OPERATOR(*))
...
CONTAINS
SUBROUTINE DO_SOMETHING(x, y)
TYPE(U) :: x
TYPE(V) :: y
x = x + x*x ! legal
y = y + y*y ! legal
x = x + y ! illegal - no supporting requirement
x = 2*x ! illegal integer multiply not in requirements
END SUBROUTINE DO_SOMETHING
END TEMPLATE TMPL2
Rationale: Restrictions are intended to be reusable in multiple
contexts. We expect that restrictions will often be
defined external to templates.
L. A template may not use any procedures or operators except those
that have been specified in a REQUIRES statement.
Rationale: This is the notion of a "strong concept" which allows
template developers to ensure that a template does not
have any implicit requirements that might not be
detected for some unanticipated template parameters.
N. A template instantiation must satisfy all imposed requirements
Note: This is the notion of a "weak concept" which requires that
invalid dummy template parameters be diagnosed as such
rather than being diagnosed is syntax or linkage errors in
the expanded code.
3. Commentary
=============
A. Subgroup has decided to disallow type-bound operators/procedures as
template parameters at this time. This does not lead to any loss
of functionality, as users can readily wrap such entities as non
type-bound operators/procedures if necessary.
4. Unresolved technical issues
==============================
UTI-1: Can operator relations in a restriction specify rank? E.g.,
INTERFACE OPERATOR(+)
FUNCTION plus(x, y) result(z)
TYPE(T), INTENT(IN) :: x, y(3)
TYPE(T) :: Z(3)
END FUNCTION
END INTERFACE
How would we express this in a relation?
UTI-2: Do procedure relations in a restriction need to specify
argument INTENT? Our suggestive syntax does not support
this. INTENT could be implicit for operators, as it must
be INTENT(IN) for these.
===END===