template useLocal(): int =
mixin local
local + 1
assert not compiles(useLocal()) # `local` not declared, so template will not compile
block:
let local = 2
assert useLocal() == 3
template insertLocal() =
let local {.inject.} = 2
block:
insertLocal()
assert local + 1 == 3
assert useLocal() == 5
Not sure if you're asking for an explanation or praising him for his concise example. But these are completely different things. mixin allows a symbol to not point to anything when it's defined, to be "bound" when the procedure or template is used:
template useLocal(): int =
mixin local # Without this the compiler would complain that local wasn't defined
local + 1
block:
let local = 2
assert useLocal() == 3 # Here the variable local defined on the line above will be used for the local variable in the procedure
block:
assert useLocal() == 3 # This will fail, for there is no local variable to bind
Another thing to keep in mind is that mixin can only really be used in templates and generic procedures since normal procs don't really have any logic on instantiation.
Now {.inject.} on the other hand is completely different. It is exclusively used in templates. Normally any variables defined in a template will not be visible outside the template, this is what is called hygienic templates. If you want to "leak" a variable out from a template you can use {.inject.} on specific variables, or you can mark the entire template {.dirty.}.
template defineLocal() =
let local = 2
defineLocal()
assert local == 2 # This will throw an error because local is not defined outside of the template
template insertLocal() =
let local {.inject.} = 2
insertLocal()
assert local == 2 # This works fine because the variable local has been injected into this scope