static[T]
As their name suggests, static parameters must be constant expressions:
proc precompiledRegex(pattern: static string): RegEx =
var res {.global.} = re(pattern)
return res
precompiledRegex("/d+") # Replaces the call with a precompiled
# regex, stored in a global variable
precompiledRegex(paramStr(1)) # Error, command-line options
# are not constant expressions
For the purposes of code generation, all static parameters are treated as generic parameters - the proc will be compiled separately for each unique supplied value (or combination of values).
Static parameters can also appear in the signatures of generic types:
type
Matrix[M,N: static int; T: Number] = array[0..(M*N - 1), T]
# Note how `Number` is just a type constraint here, while
# `static int` requires us to supply an int value
AffineTransform2D[T] = Matrix[3, 3, T]
AffineTransform3D[T] = Matrix[4, 4, T]
var m1: AffineTransform3D[float] # OK
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 parameter 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:
import std/math
echo static(fac(5)), " ", static[bool](16.isPowerOfTwo)
The compiler will report any failure to evaluate the expression or a possible type mismatch error.