Decorator for caching

does the combination of annotations and macros allow for something like a caching decorator? Such that if you have something line

@cached
def somefun(a, b)
...
end

the first call to somefun(1, 2) would actually run it and return and cache the output, but any subsequent call of somefun(1, 2) would just return the cached output?

Assuming this is in the context of a class/struct, you could leverage the block getter variant:

https://crystal-lang.org/api/master/Object.html#getter(*names,&block)-macro

Otherwise, I don’t think the annotation/macros would make sense here. You’d have to check in the method body for the annotation, and at that point you already know if it’ll have the annotation or not so my as well just hard code that logic in there.

1 Like

We use something similar in Lucky Lucky - Routing and Params There’s a memoize macro that you prepend to your method

memoize def somefun(a, b) : Whatever
 ...
end

Here’s the implementation lucky/src/lucky/memoizable.cr at main · luckyframework/lucky · GitHub

1 Like

I came from Ruby and did not know this. Looks useful.

That looks to be exactly what I need, but the comments seem to indicate that it only caches for one set of arguments, and that the cache drops existing memoizations if it is called with different params, is that correct? That would protect against hammering one specific expensive operation, but I’m looking to use it for dynamic programming, so I’d want to use it for all param sets, not just the latest.