Type System in Depth
13.1 Type Aliases vs distinct
distinct gives zero-cost type safety (units, IDs, sanitized strings).
type
UserId = int # alias: interchangeable with int
Meters = distinct float # new type: NOT interchangeable
Feet = distinct float
proc `+`(a, b: Meters): Meters {.borrow.} # borrow ops from the base type
proc `$`(m: Meters): string {.borrow.}
let d = Meters(5.0) + Meters(2.5)
# let bad = Meters(1.0) + Feet(2.0) # compile error: type safety
echo d, " ", float(d)13.2 Converters (Implicit Conversions)
converter toBool(x: int): bool = x != 0
if 1: echo "truthy" # uses the converter (use sparingly!)13.3 Type Classes and typedesc
proc describe(x: SomeNumber) = echo "number: ", x # SomeInteger, SomeFloat, SomeOrdinal...
proc zeroOf(T: typedesc): T = default(T)
echo zeroOf(int), zeroOf(string).len
proc show[T: int | string](x: T) = echo x # union type class13.4 auto and typeof
proc identity(x: auto): auto = x
var v: typeof(identity(5))13.5 Static Parameters
proc repeatN(s: string, n: static int): string =
when n > 3: {.warning: "large repeat".}
result = s.repeat(n)
type Matrix[R, C: static int] = array[R, array[C, float]]13.6 Subtyping and of
Object inheritance (Module 17): of RootObj, runtime checks with of, conversion Derived(base).
13.7 Type Introspection
import std/typetraits
echo name(int), " ", int is SomeInteger, " ", supportsCopyMem(seq[int]), " ", genericParams(seq[int])
echo default(Point), " ", typeof(1 + 2.0) # error: no mixed arithmetic without conversion