In Nim 1.0, a fix was made to disallow declaring a template of an untyped
parameter more than once. That is, this is now disallowed
template foo(x: untyped) = discard
template foo(x: untyped) = discard
Run
This is correct, and one may wonder why it was allowed before. Unfortunately,
it turns out I had used this pattern in
[memo](https://github.com/andreaferretti/memo), inadvertently, as it was
generated by a macro. Or maybe it comes from some PR I accepted, I dno't recall
exactly. But it turns out that memo generates code like this
template resetCache(x: untyped) =
when x == someFunction:
# do stuff
template resetCache(x: untyped) =
when x == someOtherFunction:
# do stuff
template resetCache(x: untyped) =
when x == YetAnotherFunction:
# do stuff
Run
As you can see, there is a `when` guard, which guarantees that at most one of
the templates will apply for a given function. But still, the generated code
does not make sense, and does not compile.
The intention here is to memoize functions - that is, store computed values in
a hash table - and be able to reset that hash table when needed. In other
words, the declaration
proc f(x: int): int {.memoized.} =
# body here
Run
is translated into something like
var table12345 = initHashTable[int, int]()
proc f12345(x: int): int =
# body here
proc f(x: int): int =
if not x in table12345:
table12345[x] = f12345(x)
return table12345[x]
template resetCache(x: untyped) =
when x == f:
table12345 = initHashTable[int, int]()
Run
where the names `table12345` and `f12345` are gensymmed.
What could be a way to prevent the name clash? I could collect all associations
function -> cache at compile time, but then I need some way to generate a
single `resetCache` template before it is used.
Right now, memo does not compile, and I am trying to fix it as I have been
updating all my libraries for Nim 1.0 compatibility.