I am trying to get the following code to compile
proc square[T](data: T): T =
return data*data;
proc cube[T](data: T): T =
return data*data*data
template isValid[T](fun: proc (data: T): T {.closure.}): bool =
(fun == cube[T]) or (fun == square[T])
template passFun*[T](fun: proc (data: T): T {.closure.}, data: T): T =
const cond: bool = isValid(fun); # error occurs here
when (not cond):
assert(false, "... this is not a valid function.");
fun(data);
echo "pass the square function: ", passFun(square, 2.0);
and I get the error:
template/generic instantiation of `passFun` from here
Error: cannot instantiate: 'T'
isValid limits the proc that can be run even further. I guess it's because isValid can not be evauated at compile time. There should be a way to do this.
If you're only ever directly naming the function names in passFun, this works:
import std/macros
proc square[T](data: T): T =
return data*data
proc cube[T](data: T): T =
return data*data*data
proc halve[T](data: T): T =
return data / 2
macro passFun(fun, data: untyped): untyped =
assert fun.repr in ["square", "cube"]
result = quote do:
`fun`(`data`)
echo "pass the square function: ", passFun(square, 2.0)
echo "pass the cube function: ", passFun(cube, 2.0)
#echo "pass the error function: ", passFun(halve, 2.0)