support for cached evaluation via weak_ref;
authorwenzelm
Mon, 08 May 2023 23:30:58 +0200
changeset 77998 cad50a7c8091
parent 77997 4660181c83c9
child 77999 ec850750db87
support for cached evaluation via weak_ref;
src/Pure/Concurrent/synchronized.ML
src/Pure/Concurrent/unsynchronized.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;
--- 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";