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
Cache initialized in memoized() macro:
...
var cache = initTable[argType, retType]() # this is runtime-only declared
...
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
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
...
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
Create a static overload:
proc complexProc(n:int):int {.memoized.} =
discard
proc complexProc(n: static int):int {.memoized.} =
discard