20250, "vasslitvinov", "Static array and domain types", "2022-07-19T04:58:36Z"
This is a gentler alternative to #19292. This proposal allows us to address the runtime-type-related issues in semantics and implementation and to "legalize" skyline arrays, de-facto available since #8073.
Basic Principles
We propose to introduce static array and domain types as distinct from runtime types. The static types are available during compilation, with user-facing semantics.
-
Each runtime type has a corresponding static type. The static type is obtained from a runtime type by discarding the runtime component.
-
The type of an expression is a runtime type only in the cases where the runtime component is available. Otherwise it is a static type.
-
Generic types - other than array/domain types - are always instantiated with static types.
-
When the type of a variable is declared with a static array/domain type, it cannot be default-initialized.
Here "variable" includes fields, tuple components, array elements, and formals.
Details
- Even though a generic type is instantiated with static type(s), runtime type(s) can sometimes be obtained from values of this type. For example:
var A: [D] real;
type RTT = A.type; // RTT is a runtime array type
type STT = the static type of A; // STT is a static array type
record R1 { type t; }
var r1 = new R1(RTT); // r1.type = R1(STT)
// r1.type.t = STT
// r1.t = RTT <----- based on the value r1
type T1 = R1(RTT); // T1 = R1(STT)
// T1.t = STT
record R2 { var x; }
var r2 = new R2(A); // r2.type = R2(STT)
// r2.x.type = RTT <----- based on the value r2.x
type T2 = R2(RTT); // T2 = R2(STT)
// T2.x = STT
-
Consider a variable declared with a static array/domain type. Once it is initialized,
aVariable.type
returns a runtime type. This runtime type is derived from the value held inaVariable
. -
An array/domain-typed field in a record can be default-initialized as long as there is a corresponding runtime type coming into the initializer. For example:
record R3 {
type t;
var x: t;
proc init(type t) {
this.t = t;
// x is default-initialized
}
}
var r3 = new R3(myArray.type); // default initialization is OK because
// `t` is a runtime type in the initializer
// runtime types: r3.t, r3.x.type
// static types: r3.type.t, R3(myArray.type).t, R3(myArray.type).x
-
Skyline arrays are where this proposal shines. The element type of a skyline array is a STATIC array type. We cannot get to the domain of the element type from the type of the skyline array itself. Cf. the runtime type of a given element of a skyline array A is available as
A[i].type
. -
When an array stores an iterable expression with array elements, the enclosing array's element type is static. This is somewhat similar to skyline arrays.
-
A static array type could be written as
[domain(2)] real
. -
We could introduce a built-in method
EXPR.staticType
that produces the static type when EXPR is an array/domain value or type. In the other cases it is the same as EXPR.type.
Related issues
Bugs:
#11549 handle record and class types with runtime types
#15929 Problem with runtime type and default initialization
#20050 internal compiler error / instantiating a type field with an array type
Semantics:
#8152 what should .eltType
do for skyline arrays?
#11220 Runtime type for an array of arrays
Skyline-related:
#11254 forall-over-forall results in empty array
#11039 for/forall expression with arrays as elements does not work
#11884 avoid extra iterator invocation upon reduce
#11882 avoid evaluating the argument of .type (see the discussion)