0

Been messing around with functional programming concepts and came across memoization.

Here's an example:

public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> f) {
    var cache = new ConcurrentDictionary<T, TResult>();
    return a => cache.GetOrAdd(a, f);
}

How does the returned function still have access to the dictionary object?

  • A reference to the dictionary is kept by the lambda, in turn preventing garbage collection of `cache` even after the thread leaves `Memoize()`, [according to the docs](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#capture-of-outer-variables-and-variable-scope-in-lambda-expressions) – Mathias R. Jessen Apr 14 '20 at 17:46
  • That is way overkill to memoize a variable by the way, holding an entire dictionary for the one value. A dictionary has at least a `List` and a tree (a heap) inside, plus a ton of helper objects to deal with concurrency. – Blindy Apr 14 '20 at 18:01
  • @Blindy, I think (or hope) the point is to implement a cache for many values. – ChiefTwoPencils Apr 14 '20 at 23:14
  • @Blindy There would be many values in this dictionary, not just one – Frog Baxter Apr 14 '20 at 23:41
  • Not the way you wrote it, you create a new dictionary for every call, and push exactly one value in it. – Blindy Apr 15 '20 at 14:54

1 Answers1

0

What you are doing here is creating a kind of a closure, because of which the reference to Dictionary.GetOrAdd method, via an inner variable cache, is still accessible from outside of the Memorize method.

Because of this, while C# program scope, where the returned function value for the Memorize method is still active, will also prevent a Garbage collector from releasing memory for the Dictionary.

More about closures also here.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42