# HG changeset patch # User wenzelm # Date 1683581458 -7200 # Node ID cad50a7c809158ca060fbe871d9edac12f2a2511 # Parent 4660181c83c984f78fb95e5cb00ed00cb04d3d3a support for cached evaluation via weak_ref; diff -r 4660181c83c9 -r cad50a7c8091 src/Pure/Concurrent/synchronized.ML --- a/src/Pure/Concurrent/synchronized.ML Mon May 08 23:00:17 2023 +0200 +++ b/src/Pure/Concurrent/synchronized.ML Mon May 08 23:30:58 2023 +0200 @@ -14,6 +14,9 @@ val guarded_access: 'a var -> ('a -> ('b * 'a) option) -> 'b val change_result: 'a var -> ('a -> 'b * 'a) -> 'b val change: 'a var -> ('a -> 'a) -> unit + type 'a cache + val cache: (unit -> 'a) -> 'a cache + val cache_eval: 'a cache -> 'a end; structure Synchronized: SYNCHRONIZED = @@ -92,4 +95,24 @@ end; + +(* cached evaluation via weak_ref *) + +abstype 'a cache = + Cache of {expr: unit -> 'a, var: 'a Unsynchronized.weak_ref option var} +with + +fun cache expr = + Cache {expr = expr, var = var "Synchronized.cache" NONE}; + +fun cache_eval (Cache {expr, var}) = + change_result var (fn state => + (case state of + SOME (Unsynchronized.ref (SOME (Unsynchronized.ref result))) => (result, state) + | _ => + let val result = expr () + in (result, SOME (Unsynchronized.weak_ref result)) end)); + end; + +end; diff -r 4660181c83c9 -r cad50a7c8091 src/Pure/Concurrent/unsynchronized.ML --- a/src/Pure/Concurrent/unsynchronized.ML Mon May 08 23:00:17 2023 +0200 +++ b/src/Pure/Concurrent/unsynchronized.ML Mon May 08 23:30:58 2023 +0200 @@ -7,7 +7,6 @@ signature UNSYNCHRONIZED = sig datatype ref = datatype ref - type 'a weak_ref = 'a ref option ref val := : 'a ref * 'a -> unit val ! : 'a ref -> 'a val change: 'a ref -> ('a -> 'a) -> unit @@ -16,6 +15,8 @@ val dec: int ref -> int val add: int ref -> int -> int val setmp: 'a ref -> 'a -> ('b -> 'c) -> 'b -> 'c + type 'a weak_ref = 'a ref option ref + val weak_ref: 'a -> 'a weak_ref end; structure Unsynchronized: UNSYNCHRONIZED = @@ -23,8 +24,6 @@ datatype ref = datatype ref; -type 'a weak_ref = 'a ref option ref; - val op := = op :=; val ! = !; @@ -44,6 +43,9 @@ val _ = flag := orig_value; in Exn.release result end) (); +type 'a weak_ref = 'a ref option ref; +fun weak_ref a = Weak.weak (SOME (ref a)); + end; ML_Name_Space.forget_val "ref";