static[T]

As their name suggests, static parameters must be constant expressions:

  1. proc precompiledRegex(pattern: static string): RegEx =
  2. var res {.global.} = re(pattern)
  3. return res
  4. precompiledRegex("/d+") # Replaces the call with a precompiled
  5. # regex, stored in a global variable
  6. precompiledRegex(paramStr(1)) # Error, command-line options
  7. # are not constant expressions

For the purposes of code generation, all static params are treated as generic params - the proc will be compiled separately for each unique supplied value (or combination of values).

Static params can also appear in the signatures of generic types:

  1. type
  2. Matrix[M,N: static int; T: Number] = array[0..(M*N - 1), T]
  3. # Note how `Number` is just a type constraint here, while
  4. # `static int` requires us to supply an int value
  5. AffineTransform2D[T] = Matrix[3, 3, T]
  6. AffineTransform3D[T] = Matrix[4, 4, T]
  7. var m1: AffineTransform3D[float] # OK
  8. var m2: AffineTransform2D[string] # Error, `string` is not a `Number`

Please note that static T is just a syntactic convenience for the underlying generic type static[T]. The type param can be omitted to obtain the type class of all constant expressions. A more specific type class can be created by instantiating static with another type class.

One can force an expression to be evaluated at compile time as a constant expression by coercing it to a corresponding static type:

  1. import math
  2. echo static(fac(5)), " ", static[bool](16.isPowerOfTwo)

The compiler will report any failure to evaluate the expression or a possible type mismatch error.