Skip to content

Generic inference and default values

GenericCall = Callee [ TypeArguments ] "(" [ ArgumentList ] ")" .
DefaultExpression = "default" [ "(" Type ")" ] .

Type arguments may be explicit (identity<int>(3)) or inferred. Inference uses a closed receiver, value arguments matched recursively against parameter types, and a target-typed lambda’s parameter/body result. It does not infer backward from the expected result type: let xs: List<int> = make() cannot select make<T>() -> List<T>; write make<int>(). An unresolved required type argument is a located error, never an open generic call emitted to IL.

func pair<T>(a: T, b: T) -> (T, T) = (a, b)
let p = pair(1, 2) // T = int

Type parameters are unconstrained: E# has no where clauses or in/out annotations. A bare T may be stored, passed, returned, and used with default(T), but cannot be assumed to expose arbitrary members.

default(T) yields T’s CLR zero value. Bare default is target-typed and is valid in a typed return, annotated binding, assignment target, or parameter default; without such a target it is ill-formed.