nim-chronos
nim-chronos copied to clipboard
RFC: Timer callbacks don't need the "user data" pointer
Since Jacek is reviewing the AD2 APIs and suggesting changes, here is one small change I want to suggest.
The timer APIs are currently accepting a closure taking an opaque pointer type.
addTimer(node.beaconState.slotStart(slot)) do (p: pointer):
doAssert validator != nil
asyncCheck proposeBlock(node, validator, slot.uint64)
This is a common pattern used in C to simulate "closure-like" callbacks. With a native support for closures in the language, such an API is quite unnatural and less convenient. The opaque pointer can be removed without any loss of functionality.
For very low-level interop with C, Nim can provide additional helpers for wrapping a C function and pointer into a closure type and also for deconstructing the closure type to its respective pair of pointers.
not just timers, all callbacks:
CallbackFunc* = proc (arg: pointer = nil) {.gcsafe.}
If you don't need that pointer, just don't use it, but i need it in streams and other places to avoid closure environment allocation.
For very low-level interop with C, Nim can provide additional helpers for wrapping a C function and pointer into a closure type and also for deconstructing the closure type to its respective pair of pointers.
My comment above meant to address your needs.
I've just checked that system.nim already defines rawProc
and rawEnv
for accessing the closure components after it's created. I've now added a helper for going the other way around - creating a closure from the "raw" components:
https://github.com/status-im/nim-std-shims/blob/master/std_shims/closures.nim
I believe the example above covers what is needed for AD2. The signature of the helper can be made a bit more precise before the code is submitted for upstream adoption.