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.

Reply via email to