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.