to call a function it is necessary to know how (e.g. how should the parameters 
or the return value be transfered). This is what's called a calling convention.

In practice you don't have to worry about this much, except when interfacing C 
or when dealing with closures like here.

A reference to a closure is a bit different to a normal reference to a proc. 
Usually a single pointer pointing to the memory address where the proc begins 
is enough information to call it. But a closure is special because it's not 
only a proc, but it also has data associated with it captured by the proc.

Here's an example of a closure: 
    
    
    proc test(x: int): proc(): int =
       (proc(): int = x)
    
    
    Run

As you can see, the returned proc changes it's behaviour depending on the 
context it was created in, thus it needs two pointers two store the function.

It's not always desirable to have this overhead, this is why procs which don't 
capture anything are set to the non closure calling convention (like start and 
update in your example). It is possible to store a reference to a non closure 
proc in a closure proc, the second pointer then is just set to null. Before 
calling a closure it is checked whether the data pointer is null or not, if yes 
it uses the non closure calling convention (nimcall) otherwise it uses the 
closure calling convention. The other way around is of course not possible.

As I said it's possible to have references to procs with the nimcall calling 
convention saved in references in the closure calling convention. This 
conversion happens automatically for singular values like in the example where 
you show what's valid, but it doesn't work with tuples. You can perform the 
conversion before before packing the proc references into the tuple, like this: 
    
    
    ((proc())(start),(proc())(update))
    
    
    Run

For more informations check out the manual: 
[https://nim-lang.org/docs/manual.html#types-procedural-type](https://nim-lang.org/docs/manual.html#types-procedural-type)

I hope this a bit lengthy explanation helps.

Reply via email to