When a generic fn is defined before a template, and a specific fn is defined after the template, the template always uses the generic fn:
proc x[T](i: T) =
echo "generic x"
template temp(a) =
x(a)
proc x(i: int) =
echo "specific x"
temp(14)
ms:work1 jim$ ./tst
generic x
When the generic is defined after the template, Nim chooses the generic fn:
template temp(a) =
x(a)
proc x[T](i: T) =
echo "generic x"
proc x(i: int) =
echo "specific x"
temp(14)
ms:work1 jim$ ./tst
specific x
I thought it would choose the specific function in both cases. Is this expected?Yes. If you want the template to match the other function mix it in.
template temp(a) =
mixin x
x(a)
Or define another function or template before temp
proc x[T:not int](i: T) =
echo "generic x 2"
It doesn't have to match but the presence of two or more functions turns x from a closedSymChoice to an openSymChoice.
Alternatively if you want to be sure that temp doesn't match x after it's defined bind x.
template temp(a) =
bind x
x(a)
Though they look like functions, templates are strange beasts...
It seems that your template looks at the symbols it knows when it is instantiated, and it will select the most specific in the known symbols at that time. If both procs have been parsed by the compiler when invoked, it will choose the specific one.
proc x[T](i: T) =
echo "generic x"
proc x(i: int) =
echo "specific x"
template temp(a) =
x(a)
temp(14)
But if when the template is instantiated and only the generic proc symbol is known at that time, the compiler will not try to find if another overloaded proc exist. And in your example it will select the generic proc.
I would have to look at Nim sources to confirm that behaviour.
I've tried to list such template behaviours in order to complete Nim template documentation.