Yes you can, see this for example: https://github.com/mratsim/nim-rmad/blob/master/src/autograd.nim#L46-L57
Note that the proc arity (number of arguments) is part of the type, as is its calling convention (pointer/{.nimcall.} vs {.closure.}).
Thankyou for your reply @mratsim
I tried the following:
type
Data*[T] = object
id: string
contents: T
subscribers: seq[proc(d: T)]
proc addSubscriber*[T](d: T, cb: proc(d:T)) =
d.subscribers.add(cb)
proc callSubscribers[T](d: T) =
for cb in d.subscribers:
cb(d.contents)
var dd = Data[string]()
dd.contents = "a content"
dd.id = "1"
dd.subscribers = newseq[proc(d: string)]()
dd.addSubscriber(proc(d: string) = echo $d)
dd.callSubscribers()
but I get this error:
testproc.nim(19, 3) Error: type mismatch: got <Data[system.string], proc (d: string {.gcsafe, locks: 0.}>
but expected one of:
proc addSubscriber[T](d: T; cb: proc (d: T))
first type mismatch at position: 2
required type: proc (d: T){.closure.}
but expression 'proc (d: string) = echo [$d]' is of type: proc (d: string){.gcsafe, locks: 0.}
expression: addSubscriber(dd, proc (d: string) = echo [$d])
it seems I'm missing something
proc addSubscriber*[T](d: var Data[T], cb: proc(d:T)) =
d.subscribers.add(cb)
A typo T for Data[T], and var needed for add.Thank you!
this does work:
type Data*[T] = object contents: T subscribers: seq[proc(d: T)] proc createData*[T](t: typedesc[T], c: T): Data[T] = result = Data[T]() result.contents = c result.subscribers = @[] proc addSubscriber*[T](d: var Data[T], cb: proc(d:T)) = d.subscribers.add(cb) proc callSubscribers[T](d: T) = for n in d.subscribers: n(d.contents) var dd = createData(string, "data") proc print[T](d: T) = echo $d dd.addSubscriber(print) dd.callSubscribers()