I'm stuck at the following. Is there maybe a way to detect that I'm resolving a 
macro for a compileTime context rather than a runtime context?

I'm trying to upgrade the memo module. Normally, if memoizing in a runtime 
context, like the following, then the cache is initialized as such. 
    
    
    proc complexProc(n:int):int {.memoized.} =
      # this is recursive...
    ...
    proc main() =
      var fastResult = complexProc(46)
      echo fastResult
    
    
    Run

Cache initialized in `memoized()` macro:
    
    
    ...
      var cache = initTable[argType, retType]() # this is runtime-only declared
      ...
    
    
    Run

Okay, now if I want this to work in a compileTime context, I just change `var 
fastResult` to `const fastResult`: 
    
    
    proc complexProc(n:int):int {.memoized.} =
      # this is recursive...
    ...
    proc main() =
      const fastResult = complexProc(46)
      echo fastResult
    
    
    Run

BUT! I must change cache initialization to be `compileTime`, which now makes it 
unworkable for runtime contexts:
    
    
    ...
      var cache {.compileTime.} = initTable[argType, retType]() # this is 
compileTime-only declared
      ...
    
    
    Run

So, what kind of when/if statement should be there? I can't use `when nimvm` 
because it's always in nimvm.

Alternatively, I could do the macro equivalent of a global cache if I ensure 
unique ident, but I don't like that I have to check for initialization on every 
call and can't rely on `{.global.}` to do the right thing at `compileTime`. 
Perhaps this is simply the way to go and settle for the extra if statement 
penalty.

Caching that works in both compileTime and runtime contexts: 
    
    
    proc complexProc(n:int):int =
      var cache {.global.}:Table[int,int]() # with the if, works in compileTime 
and runtime contexts
      if len(cache) == 0: cache = initTable[int,int]()
      # usual recursive code
    
    
    Run

Reply via email to