Can I give a name to an anonymous procedure for debugging purpose?
callbacks.add proc() =
...
Of course, it can be achieved like this:
var procs: seq[proc(a, b: int): int]
procs.add(proc(x, y: int): int = x + y)
procs.add(proc(a, z: int): int = a - z)
echo procs[1](5, 2) # 3
You can try it on Nim Playground
Agree with the definition. What I want to do is to give a callback a name. It seems it's not working.
callbacks.add proc doSomething() =
...
Here is an example:
https://play.nim-lang.org/#ix=3Cf6
var callbacks: seq[proc()]
callbacks.add proc() =
discard
callbacks.add proc() =
raise
for callback in callbacks:
callback()
If I don't want to open the file to see which proc/callback is throwing error, a descriptive name in the stack will be very helpful.
/usercode/in.nim(10) in
/usercode/in.nim(7) :anonymous
/playground/nim/lib/system/fatal.nim(49) sysFatal
Error: unhandled exception: no exception to reraise [ReraiseDefect]
You could do something like this:
import macros, std / genasts, strformat
template named(name: string) {.pragma.}
var procs: seq[proc(a, b: int): int]
var procNames: seq[string]
macro addCallback(cb: untyped): untyped =
result = genAst(cb, name = pragma(cb)[0][1].strVal):
procNames.add name
procs.add cb
addCallback(proc(x, y: int): int {.named:"myProc1".} = x + y)
addCallback(proc(a, z: int): int {.named:"myProc2."} = raise newException(Defect, "test"); a - z)
for i, callback in procs:
try:
echo &"{i} {callback(1, 2) = }"
except:
echo "Error: ", procNames[i], " ", getCurrentExceptionMsg()
a return value like this?
let callbacks = @[ (proc():int{.named:"foo".} =
3
),
(proc ():int{.named:"foo".} =
raise
)
]
for callback in callbacks:
echo callback()
Like this
import macros
macro name*(name:static string, f: proc): untyped =
f.expectKind(nnkLambda)
result = nnkProcDef.newNimNode()
f.copyChildrenTo(result)
let id = ident(name)
result[0] = id
result = quote do:
block:
`result`
`id`
var callbacks: seq[proc(): int]
callbacks.add proc(): int {.name: "test".} =
raise
for callback in callbacks:
callback()
works on 1.6.0
on 1.4.8, change the parameter list to macro name*(name:static string, f: untyped): untyped
The preferred way would be callbacks.add proc foo() = ...
@Araq if you don't mind, I'll open a feature request in GitHub Nim project.
@Araq if you don't mind, I'll open a feature request in GitHub Nim project to accept optional name in the inlined proc.
Please don't. I understand that you really would like to have this feature but Nim is based on the "discard" paradigm. An anon proc produces a value that has to be consumed somewhere, a named proc produces void. This is a simple, particularly elegant rule (IMO anyway) and naming anon procs would make it considerably more complex for very little gain.