I have a call to a proc like that:
let v = xl.validate(f)
My validate proc is:
proc validate(xl: ExpressionList, f: SystemFunction): seq[Value] =
result = xl.list.map((x) => x.evaluate())
if unlikely(not f.req.contains(result.map((x) => x.kind))):
validationError(f.req, result, f.name)
The thing is I want to convert the validate proc to a template (for perfomance reasons).
How can I do it?
(I tried converting like the following example, but then - when using v after the call - the variable is obviously undeclared)
template validate(xl: ExpressionList, f: SystemFunction): untyped {.dirty.} =
let v = xl.list.map((x) => x.evaluate())
if unlikely(not f.req.contains(v.map((x) => x.kind))):
validationError(f.req, v, f.name)
Another idea would be to first declare the var in every calling proc, like var v: seq[Value] and then call the dirty template. But it looks a bit messy (and not sure if it'll have any performance impact). Am I missing something?
for perfomance reasons
That sounds a bit strange for me.
Have you tested proc with inline pragma already? And note when you compile with -flto you have generally full inlining for free.
I think templates may have benefit for tiny procs, when there is only one plain statement maybe.
And from my memory, replacing a proc by a template is generally very easy, just replace keyword proc by template, let parameters and result unchanged, no need for typed/untyped. Only difference is that there is no default return variable for template, so one can use var res = ...; return res. But maybe I miss something, you may be know better, you are a PhD.
you are a PhD.
LOL. If this was going for me, the "dr" part is because I was once a gonna-be (medical) doctor... But thank god, this never happened ;-)
I've notice that sometimes {.inline.} doesn't work, or worse, Nim inserts genericAux or genericAuxReset in that proc even though it's a hot path.
With templates I'm sure that this won't happen. As @Stefan_Salewski said the conversion is easy:
from
proc validate(xl: ExpressionList, f: SystemFunction): seq[Value] =
result = xl.list.map((x) => x.evaluate())
if unlikely(not f.req.contains(result.map((x) => x.kind))):
validationError(f.req, result, f.name)
to
template validate(xl: ExpressionList, f: SystemFunction): seq[Value] =
var r = xl.list.map((x) => x.evaluate())
if unlikely(not f.req.contains(r.map((x) => x.kind))):
validationError(f.req, r, f.name)
# Return the result
r
Now if performance is your concern: