Hmmm it appears nim is not a fan **at all** of making that proc-type generic there: import std/[asyncdispatch, macros, sugar] template isAsync(body: untyped): bool = typeof(body) is Future type AsyncNextProc[T] = proc(value: T): Future[void] {.async, closure.} NextProc[T] = proc(value: T) {.closure.} AsyncErrorProc = proc(error: ref CatchableError): Future[void] {.async, closure.} ErrorProc = proc(error: ref CatchableError) {.closure.} AsyncCompleteProc = proc(): Future[void] {.async, closure.} CompleteProc = proc() {.closure.} Observer*[T] = ref object next*: AsyncNextProc[T] error*: AsyncErrorProc complete*: AsyncCompleteProc proc newObserver*[T]( next: NextProc[T] | AsyncNextProc[T], error: ErrorProc | AsyncErrorProc = nil, complete: CompleteProc | AsyncCompleteProc = nil ): Observer[T] = const nextProc = when isAsync(next(default(T))): next else: proc(value: T){.async, closure.} = next(value) const errorProc = when isAsync(error(nil)): error else: proc(exception: ref CatchableError){.async, closure.} = error(exception) const completeProc = when isAsync(complete()): complete else: proc(){.async, closure.} = complete() return Observer[T]( next: nextProc, error: errorProc, complete: completeProc, ) let obs = newObserver[int](proc(value: int) = echo value) Run
Leads to `Error: expression 'newObserver[int](proc (value: int) = echo [value])' cannot be called` ... do I really have to write out every single permutation of these 3 procs and hard-code the transformation from sync to async proc?