Type erasure
Type erasure is the process of setting a type argument to _
and deliberately discarding its information. Type erasure is a feature of many polymorphic languages, but in the context of Erg's syntax, it is more accurate to call it type argument erasure.
The most common example of a type that has been type-erased is [T, _]
. Arrays are not always known their length at compile-time. For example, sys.argv
, which refers to command line arguments, is of type [Str, _]
. Since Erg's compiler has no way of knowing the length of command line arguments, information about their length must be given up.
However, a type that has been type-erased becomes a supertype of a type that has not been (e.g. [T; N] <: [T; _]
), so it can accept more objects.
Objects of type [T; N]
can of course use methods of type [T; _]
, but the N
information is erased after use. If the length does not change, then it is possible to use [T; N]
in the signature. If the length remains the same, it must be indicated by a signature.
# Functions that are guaranteed to not change the length of the array (e.g., sort)
f: [T; N] -> [T; N] # functions that do not (f: [T; N])
# functions that do not (e.g. filter)
g: [T; n] -> [T; _]
If you use _
in the type specification itself, the type is upcast to Object
.
For non-type type arguments (Int, Bool, etc.), the parameter with _
will be undefined.
i: _ # i: Object
[_; _] == [Object; _] == Array
Type erasure is not the same as omitting a type specification. Once the type argument information has been erased, it will not be returned unless you assert it again.
implicit = (1..5).iter().map(i -> i * 2).to_arr()
explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
In Rust, this corresponds to the following code.
#![allow(unused)] fn main() { let partial = (1..6).iter().map(|i| i * 2).collect::<Vec<_>>(); }
Erg does not allow partial omission of types, but uses higher-order kind polymorphism instead.
# collect is a higher-order Kind method that takes Kind
hk = (1..5).iter().map(i -> i * 2).collect(Array)
hk: Array(Int)