# Copyright 2005-2007 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ ? def memoize := # value: ? memoize(def _ {}) # problem: <__main$_> is not DeepFrozen ? def f implements DeepFrozen { > to run(a, b) :any { return a + b } > # ... > } # value: ? def g :DeepFrozen := memoize(f) # value: > ? g(1, 2) # value: 3 ? g(1, 2) # value: 3 ? var i := 0 > for _ in 1..2 { > println(g(def _ { to add(_) :any {return i += 1} }, ['a'])) > } # stdout: 1 # 2 # --- Non-DeepFrozen inputs are harmless ? def noticer { match msg { println(msg); E.callWithPair(1, msg) } } # value: ? g(noticer, 1) # stdout: ["add", [1]] # # value: 2 ? g(noticer, 1) # stdout: ["add", [1]] # # value: 2 --- By default, (DeepFrozen &! Data) are not cached, because that would cause multiple calls which would have returned different (fresh) results to return the same. ? { def h implements DeepFrozen { to run() :any { return [def x {}] }} > [h(), h() == h()] } # value: [[], false] ? { def h := memoize(def _ implements DeepFrozen { to run() :any { return [def x implements DeepFrozen {}] }}) > [h(), h() == h()] } # value: [[], false] --- However, this can be overridden. ? { def h := memoize.interning(def _ implements DeepFrozen { to run() :any { return [def x implements DeepFrozen {}] }}) > [h(), h() == h()] } # value: [[], true] --- Various erroneous inputs x ? memoize(null, null) x # problem: no such method: org.cubik.cle.prim.Null#extract/2 ? memoize([].asMap(), null) # value: x ? memoize(["x" => "y"], null) x # problem: unused elements in matched map: ["x" => "y"] x ? memoize(["constant" => "foo"], null) x # problem: the String "foo" doesn't coerce to a boolean XXX these tests written when I thought I was going to add options XXX memoization options: Whether cache keys are weak: * Yes, for Selfish keys * No, for Selfless keys that are likely to recur * Perhaps a default policy of keeping a weak and a non-weak map? Maximum table size, and therefore discard policy Whether non-DeepFrozen returns are errors Whether non-DeepFrozen base means to not memoize it