Can someone explain this
type A* = object of RootObj
p: int
type
B* = object of A
q: int
type
C* = object of A
r: string
proc g[T](d: string) =
when T is B:
let l = (first: -1, last: 0)
echo(d.substr(l.first, l.last))
proc g[T]( k: string, d: string) =
let l = (first: -1, last: 0)
echo(d.substr(l.first, l.last))
proc f[T](d: string): seq[T] =
result = newSeq[T]()
g[T](d)
echo "g[T]( d)"
proc f[T](k: string, d: string): seq[T] =
result = newSeq[T]()
g[T](k, d)
echo "g[T](k, d)"
let d = ""
let t = f[B](d)
let sk = f[C]("SM", d)
Compiling gives
d:\temp\test2.nim(34, 11) template/generic instantiation of `f` from here
d:\temp\test2.nim(24, 7) template/generic instantiation of `g` from here
d:\temp\test2.nim(16, 17) Error: undeclared identifier: 'l'
The second call to f resolves to the first definition of f with arity 1 instead of the second one.
Changing the first definition of g to
proc g[T](d: string) =
echo(d)
makes it compile
I think that it may complain about the first g[T] proc. It only works in the case T = B but unless that's the case you never create the variable l. So either you have to indent the echo statement to be within the when statement or you add a else statement to the when statement to handle the case where T isn't B, and define the variable l there as well.
Writing this from my phone so can't really write the code but I hope you get the point.
The issue is that you only define l in g when it is called with type B. In the let sk line however you call f with type C, which calls g with the same type. Thus, the when branch isn't part of the g proc for that case. So l is never defined.
Is that clear?
f[C]("SM", d)
to call proc f[T](k: string, d: string)
but it is calling proc f[T](d: string)
instead. Not sure if this is a bug in the compiler or my understanding of how generic functions work when they are overloaded like this.It's not actually calling
proc g[T](d: string)
without B.
What it's doing is
instantiate g1 withB
instantiate g2 withB
instantiate g1 withC
instantiate g2 withC
call g1 withB
call g2 withC
It only comes up when you explicitly pass in generic parameters. All functions that match the generic parameters are instantiated.
It may be a bug or an implementation detail.
Either way I would report the issue on github.