-
Notifications
You must be signed in to change notification settings - Fork 23
Open
Description
(originally discussed here: nim-lang/Nim#11722 (comment) /cc @krux02 )
proposal1
proc overloadExists(expr: untyped): bool {.magic:"overloadExists".} # in system.nim (needed for `untyped` in proc)overloadExists(foo(args))compiler magic that checks whetherfoo(args)has a proper overload; it doesn't try to compilefoo(args); in particular, the check succeeds even iffoo(args)has a fwd declaration and no definition.
examples:
doAssert overloadExists(toUpper("abc"))
doAssert not overloadExists(toUpper(12))
doAssert overloadExists(1+1)
doAssert not overloadExists(1+1.2)
doAssert not overloadExists(nonexistant(1))proposal2
independent / orthogonal to proposal1. This selects a particular overload via overloadResolve. Works with any routine (template/macro/iterator/generics, regardless of all optional params/varargs)
const fooParticularOverload = overloadResolve foo("1", true)
echo fooParticularOverload("bar", false)
# this is helpful for debugging among other use cases:
echo inspect(fooParticularOverload) # can be done via https://github.com/nim-lang/Nim/pull/11754 or even just #11992
# would print:
template fooParticularOverload(x: string|cstring, y = false, z = 0): untyped declared at foo/bar.nim(12,14)this 2nd proposal requires nim-lang/Nim#11992
rationale
depending on compiles(foo(args)) can be problematic for a number of reasons:
- compiles causes CT overhead, which can be significant depending on what's being compiled; eg:
when compiles(expensiveCalculation(args)): # foo(args) executed here
expensiveCalculation(args) # executed here again
else: workaround(args)- compiles can have side effects, eg:
proc foo() =
const s = gorge("echo bar > /tmp/z01.txt")
echo s
when compiles(foo()): echo "ok1"
else: echo "ok2"The side effect can even be executed when the compiles() eventually fails after the side effect
- the
compiles(foo(args))can fail for a reason the user did not expect, eg a bug in proc body; that bug may end up not getting caught; eg:
proc fun[T: Ordinal | Foo1 | Foo2](a: T) = # contains a bug that affects some `T`
proc workaround[T](a: T) = discard
when compiles(fun(args)): # fails for some T in `Ordinal | Foo1 | Foo2`
fun(args)
else: workaround(args)here user expects fun(args) to compile for every T in Ordinal | Foo1 | Foo2 but in fact some cases may trigger the other branch to be taken due to a bug inside fun
mratsim, Vindaar, alehander92, Araq and JakeLeahyRMIT
Metadata
Metadata
Assignees
Labels
No labels