(* Futures: representation for values that are possibly not yet known *) open Wire open Rpc_t type 'a future_t = | Local of 'a * 'a typerep (* The value is known locally *) | Var of varname * 'a typerep (* Variable: the value is not known *) | Tag of tagname * 'a typerep (* Name of a remote fn: only the server knows that value *) | Exc of string (* Remote or communication exception *) ;; let gensym = let counter = ref 0 in fun () -> incr counter; !counter let newvar : 'a typerep -> varname * 'a future_t = fun typerep -> let varname = gensym () in (varname, Var (varname,typerep)) ;; (* Serialization and deserialization for futures *) let future_to_chr_val : 'a future_t -> chr_val = function | Local (x,typerep) -> UVal (gen_to_wire typerep x) | Var (x,_) -> UVar x | Tag (x,_) -> UTag x | Exc e -> failwith e (* expose the exception *) ;; (* Set the future from the partial value received from the wire *) let future_from_wire v = function | Err e -> v := Exc e | Datum w -> begin match !v with | (Var (_,typerep)) -> (match gen_from_wire typerep w with | Err e -> v := Exc e | Datum x -> v := Local (x,typerep)) | _ -> failwith "The value was already computed?" end ;;