A factory centralizes construction so callers request an object without directly invoking its representation-specific constructor. Here, the technique is motivated by memoization: repeated requests for the same immutable value return one shared instance instead of creating duplicates. section 4.3.4 section 4.3.5
A memoizing factory combines construction with identity management:
- Accept construction inputs and use them as a dictionary key. section 4.3.4
- Construct the result only on the first request for those inputs. section 4.3.4
- Return the cached result on later requests, enabling reference equality for equivalent immutable values. section 4.3.5
- Expose cache size and clearing because an uncontrolled cache can become a memory leak and impose its own performance cost. section 4.3.4
Memoized quadtree construction
Two factories construct general quadtrees and empty quadtrees. A quadtree checks emptiness by comparing itself with the factory’s canonical empty value at the same level, while a private constructor keeps creation behind the factory. section 4.3.5
Memoized term construction
Memoized factories for symbols, constants, and terms deduplicate immutable structures, making equality comparisons cheaper and transforming an exponentially large repeated term graph into a linear-size representation. section 10.2
Listing 4.3 A general-purpose one-argument memoizer
sealed class Memoizer<A, R> where A : notnull
{
private Dictionary<A, R> dict;
private readonly Func<A, R> f;
public Memoizer(Func<A, R> f)
{
this.dict = new Dictionary<A, R>();
this.f = f;
}
public R MemoizedFunc(A a)
{
if (!dict.TryGetValue(a, out R? r))
{
r = f(a);
dict.Add(a, r);
}
return r;
}
public void Clear(Dictionary<A, R>? newDict = null)
{
dict = newDict ?? new Dictionary<A, R>();
}
public int Count => dict.Count;
}
Inspect a compact C# factory that wraps a pure one-argument function, caches results, reports its size, and resets its dictionary. section 4.3.4










