Hi!
I need to generate a parametrized template with a proc defined in it, which accepts a type and returns the type instance.
When I define such proc manually, there's no issue. But when I define it within the tempale, compilation fails with undefined identifier error. Here's the minimal code sample that reproduces the issue:
import macros
type Typ = object
template makeTmpl(param: int): untyped =
  template tmpl(body: untyped): untyped =
    let otherParam = param * 2
    proc prc(T: type): T = echo otherParam
macro mac(param: int, body: untyped): untyped =
  result = newStmtList()
  result.add getAst(makeTmpl(param))
  result.add body
# This causes compilation error
mac 42:
  tmpl:
    discard Typ.prc()
# This works fine
let otherParam = 123
proc prc2(T: type): T = echo otherParam
discard Typ.prc2()
Any help would be extremely valuable as I'm completely lost. As far as my understanding goes, templates are just a way to insert raw code chunks, so defining a proc manually and inserting it with a template should be the same thing. And this code sample shows me that I am misunderstanding something.
P.S. I'm deliberately not explaining the reasons behind me wanting to write specifically this code because 1) this would be too long and 2) I really want to strip the issue alone disregarding the context and understand why this happens.
UPD: It compiled when I made both templates {.dirty.}. So the issue is solved (we really need a way to update thread titles).
However, if anyone could explain why that helped, I'd be really grateful.
Whether a symbol that is declared in a template is exposed to the instantiation scope is controlled by the inject and gensym pragmas: gensym'ed symbols are not exposed but inject'ed are.
The default for symbols of entity type, var, let and const is gensym and for proc, iterator, converter, template, macro is inject. However, if the name of the entity is passed as a template parameter, it is an inject'ed symbol
try this:
 prc[A](T: type[A]): A = echo otherParamFor that matter I'm not even sure
 proc prc2(T: type): T = echo otherParam  proc prc[A](T: type[A]): A = echo otherParam  prc(int)