> The documentation about templates is not as detailed as other parts of the
> manual.
The documentation is pretty complete, there's just not much more to say. It
lists the differences between using a template and manually putting the
template body into a program's source code, and there aren't many. Almost all
of them have to do with symbol/identifier interaction between the template body
and the rest of the code (binding and scoping), only one is a syntactic
difference: the id construction with backticks that you already used. It is
also the only thing which is actually evaluated at compile time in the template
body. Apart from that, the body is just substituted, _not_ executed.
> Trying to save typ for use in another dependent template will generate the
> error message Error: undeclared identifier: 'fast'.
Nothing can be "saved" in the template body before it has been substituted,
because its body statements are not executed at compile time. After
substitution, a template parameter cannot be "saved" because it doesn't exist
anymore then. What is still there is the substitution result of the template
parameter, which is a different thing.
Even if the parameter was still around, it could not be stored as a `let` value
because it's type, `undeclared`, is not a concrete one but a meta-type.
And all this aside, would you complain if this code snippet
template dsl(typ: untyped; myVar: untyped; code: untyped) =
let myLet = myVar
let keepTyp = typ
`typ Algo`()
code
Run
produced an error when called with a `myVar` parameter which doesn't exist in
the calling context of the template? How is the compiler to know that the first
`let` statement is a regular substitution while the second one is supposed to
"save" something it doesn't know about without throwing an error?
The only way to reuse `typ` I can think of is using it in a nested template,
which has disadvantages:
template dsl(typ: untyped; code: untyped) =
block:
template superDsl(scode: untyped) =
`Super typ Algo`()
scode
`typ Algo`()
code
dsl fast:
# Call `fastAlgo`()
echo "running"
superDsl:
# Call `SuperfastAlgo`()
echo "running super"
Run
> 6\. Is it possible to process `untyped` values in templates?
Templates don't process, they substitute.