First code:
Let's start with why any of this template's instantiation won't compile --- it
has a type error. "44" is a string but you assign it to an int variable. In
fact, Nim's type inference makes it redundant for you to specify these
variables' types.
Secondly: templates provide something called hygiene. It means that what you
see inside the template is a _local_ name. In fact, a new name is generated
each time a template is instantiated. For example:
template someCode(): untyped =
var
fname: string = "Mark"
age: int = 44
someCode()
someCode() # ok, this instantation's `fname` is a NEW `fname`
To avoid this and inject symbols directly into the scope of instantiation,
{.inject.} pragma should be used:
template someCode(): untyped =
var
fname {.inject.}: string = "Mark"
age {.inject.}: int = 44
someCode()
someCode() # error, redefinition of `fname`
echo fname # compiles, prints "Mark"
Second code:
Unluckily, Nim's no Lisp. A template or macro call is first parsed as a call
and _then_ substituted with the code yielded. It's quite unfortunate for some
cases but if your example code is more-or-less what you need, here is a
solution:
template someCode(name: untyped): untyped =
type name {.inject.} = object
fname: string
age: int
By the way... Funny thing...
type name = object
fname: string # Error: cannot use symbol of kind 'var' as a 'field'
age: int
var fname = "Mark"
var age = 44
# compiles
var fname = "Mark"
var age = 44
type name = object
fname: string # Error: cannot use symbol of kind 'var' as a 'field'
age: int
# compilation aborted
It seems to me it means something is wrong with Nim's symbol lookup. Or am I
missing something?