Hi, I have a question about templates.
It is possible to declare a variable within a template:
template declare_var(varName: untyped, var_type: type) =
var varName: var_type
I can also declare a variable in a generic template:
template declare_var_generic[T](varName: untyped) =
var varName: T
When I use these templates, e.g. like this:
proc non_gen() =
declare_var(a, int)
a = a + 5
declare_var_generic[int](b)
b = b + 5
everything is OK.
However, if I want to use these templates in a generic procedure, like this:
proc gen[T]() =
declare_var(a, int)
a = a + 5
declare_var_generic[int](b)
b = b + 5
declare_var(c, T)
c = c + 5
declare_var_generic[T](d)
d = d + 5
var e: T
e = e + 5
Then the compiler outputs an 'undeclared identifier:' for all variables (a-d).
I don't understand why? Is it because of when templates are 'resolved'? And is there another, correct way to do this?
It works if all the template parameters are not untyped and the template isn't generic.
template declare_var(varName: untyped, var_type: untyped) =
var varName {.inject.}: var_type
proc gen[T]() =
declare_var(a, int)
a = a + 5
declare_var(c, T)
c = c + 5
var e: T
e = e + 5
gen[float]()
This has to do with the early analysis of generic procs before they are even instantiated, which checks if some symbols are defined or not. I guess this mechanism accounts for fully untyped templates potentially defining new variables, but not partially typed ones. We can work around this with mixin but it's ugly:
template declare_var(varName: untyped, var_type: type) =
var varName: var_type
template declare_var_generic[T](varName: untyped) =
var varName: T
proc gen[T]() =
mixin a, b, c, d
declare_var(a, int)
a = a + 5
declare_var_generic[int](b)
b = b + 5
declare_var(c, T)
c = c + 5
declare_var_generic[T](d)
d = d + 5
var e: T
e = e + 5
gen[float]()
gen[int]()