@mora I don't see how your example would not work @jcosborn syntax:
type Has[T] = concept c
type T = type(g.gimme())
Then `T` is determined and one could treat it as a concrete type in subsequent
statements (i.e. - when another `T` appears, it must be the same)
About `static[T]`: I am using it a lot. It is very useful whenever you want to
encode some invariant in your type. An example is vectors of known length - to
avoid performing, say, matrix/vector multiplications where the dimensions do
not match (see linalg).
Another example is modular arithmetic with a fixed modulo:
type Modulo[M: static[int]] = distinct int
proc modulo(a: int, M: static[int]): Modulo[M] = Modulo[M](a %% M)
proc `+`[M: static[int]](a, b: Modulo[M]): Modulo[M] = (a.int +
b.int).modulo(M)
proc `$`*[M: static[int]](a: Modulo[M]): string = $(a.int) & " mod " & $(M)
when isMainModule:
let
a = 3.modulo(7)
b = 5.modulo(7)
echo a + b