10. Type Promotion
Type promotion is a sub-problem of casting and refers to casts that happen implicitly.
Any conversion that can be done implicitly via promotion can also be done explicitly via typecast expression.
10.1. Scalars
The only automatic type promotion for scalars is integer
to
real
. This promotion is one way - a real
cannot be automatically
converted to integer
.
Automatic type conversion follows this table where N/A means no implicit
conversion possible, id means no conversion necessary,
as<toType>(var)
means var of type “From type” is converted to type
“toType” using semantics from .
To type |
|||||
From type |
boolean |
character |
integer |
real |
|
boolean |
id |
N/A |
N/A |
N/A |
|
character |
N/A |
id |
N/A |
N/A |
|
integer |
N/A |
N/A |
id |
as<real>(var) |
|
real |
N/A |
N/A |
N/A |
id |
10.2. Scalar to Vector or Matrix
All scalar types can be promoted to vector or matrix types that have an internal type that the scalar can be converted to implicity. This can occur when a vector or matrix is used in an operation with a scalar value.
The scalar will be implicitly converted to a vector or matrix of equivalent dimensions and equivalent internal type. For example:
integer i = 1;
integer[*] v = [1, 2, 3, 4, 5];
integer[*] res = v + i;
res -> std_output;
would print the following:
[2 3 4 5 6]
Other examples:
1 == [1, 1] // True
1..2 || 3 // [1, 2, 3]
Note that a vector or matrix can never be downcast to a scalar, even if type casting is used. Also note that matrix multiply imposes strict requirements on the dimensionality of the the operands. The consequence is that scalars can only be promoted to a matrix if the matrix multiply operand is a square matrix (\(m \times m\)).
10.3. Tuple to Tuple
Tuples may be promoted to another tuple type if it has an equal number of internal types and the original internal types can be implicitly converted to the new internal types. For example:
tuple(integer, integer) int_tup = (1, 2);
tuple(real, real) real_tup = int_tup;
tuple(char, integer, boolean[2]) many_tup = ('a', 1, [true, false]);
tuple(char, real, boolean[2]) other_tup = many_tup;
Field names of tuples are overwritten by the field names of the left-hand side in assignments and declarations when promoted. For example:
tuple(integer a, real b) foo = (1, 2);
tuple(real c, real) bar = foo;
foo.a -> std_output; // 1
foo.b -> std_output; // 2
bar.a -> std_output; // error
bar.b -> std_output; // error
bar.c -> std_output; // 1
If initializing a variable with a tuple via Type Inference, the variable is assumed to be the same type. Therefore, field names are also copied over accordingly. For example:
tuple(real a, real b) foo = (1, 2);
tuple(real c, real d) bar = (3, 4);
var baz = foo;
baz.a -> std_output; // 1
baz.b -> std_output; // 2
baz = bar;
baz.a -> std_output; // 3
baz.b -> std_output; // 4
It is possible for a two sided promotion to occur with tuples. For example:
boolean b = (1.0, 2) == (2, 3.0);
10.4. Character Vector to/from String
A string
can be implicitly converted to a vector of character
s and vice-versa (two-way type promotion).
string str1 = "Hello"; /* str == "Hello" */
character[*] chars = str; /* chars == ['H', 'e', 'l', 'l', 'o'] */
string str2 = chars || [' ', 'W', 'o', 'r', 'l', 'd']; /* str2 == "Hello World" */