#[memoize]Expand description
Memoize a function.
This attribute can be applied to free-standing functions as well as methods in inherent and trait impls.
Kinds of arguments
Memoized functions can take three different kinds of arguments:
-
Hashed: This is the default. These arguments are hashed into a high-quality 128-bit hash, which is used as a cache key.
-
Immutably tracked: The argument is of the form
Tracked<T>. These arguments enjoy fine-grained access tracking. This allows cache hits to occur even if the value ofTis different than previously as long as the difference isn’t observed. -
Mutably tracked: The argument is of the form
TrackedMut<T>. Through this type, you can safely mutate an argument from within a memoized function. If there is a cache hit, comemo will replay all mutations. Mutable tracked methods can also have return values that are tracked just like immutable methods.
Restrictions
The following restrictions apply to memoized functions:
-
For the memoization to be correct, the
Hashimplementations of your arguments must feed all the information they expose to the hasher. Otherwise, memoized results might get reused invalidly. -
The only obversable impurity memoized functions may exhibit are mutations through
TrackedMut<T>arguments. Comemo stops you from using basic mutable arguments, but it cannot determine all sources of impurity, so this is your responsibility.
Furthermore, memoized functions cannot use destructuring patterns in their arguments.
Example
/// Evaluate a `.calc` script.
#[comemo::memoize]
fn evaluate(script: &str, files: comemo::Tracked<Files>) -> i32 {
script
.split('+')
.map(str::trim)
.map(|part| match part.strip_prefix("eval ") {
Some(path) => evaluate(&files.read(path), files),
None => part.parse::<i32>().unwrap(),
})
.sum()
}