According to the manual, anonymous (or otherwise) nested procs become closures if they "access local variables from their enclosing scope". In particular,
The closure environment may be allocated on the heap or on the stack if the compiler determines that this would be safe.
which worries me a little. When writing performance sensitive code, it's important to know more than "may be allocated ... on the stack". Digging into the compiler source at genClosureCall (in ccgcalls.nim), it seems that the closure environment is stack allocated when the proc returns:
To illustrate, for instance, in the code:
proc f(p: proc()) = p()
var a = 1
f do ():
var b = 2
f do ():
var c = 3
let d = a + b + c
I'd assume no heap allocations occur.
Is it simply the nested proc's return type, as described above, that determine's whether variables are heap or stack allocated? If that's so, I'm sure we could write a straight-forward rule for such situations. Maybe it should be added to the manual? Surely there are others who wonder about the performance properties of closures.
Okay. A closure call causes a heap allocation only if a variable capture occurs. Thanks for the clarification.
Closures are a bit more flexible than templates where overloading (see here) is concerned. Though you're right: templates provide strong guarantees. I'll focus in that direction.
Thinking about the difficulties of a C backend, it seems this is a situation where more flexible calling conventions would help. An LLVM backend, perhaps? I'd be very sorry to lose Nim's amazing C and C++ interfacing, though.