package timed

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Timed references for imperative state. This module provides an alternative type for references (or mutable cells) supporting undo/redo operations. In particular, an abstract notion of time is used to capture the state of the references at any given point, so that it can be restored. Note that usual reference operations only have a constant time / memory overhead (compared to those of Stdlib).

  • author Christophe Raffalli
  • author Rodolphe Lepigre

Note that this module allocates two blocks of memory at initialization for its internal state. They occupy a total of six words.

type 'a ref

Type of references similar to Stdlib.ref. Note that it uses three words of memory, while Stdlib.ref uses two. Importantly, note that it is unsafe to marshal elements of this type using functions of the Marshal module or Stdlib.output_value. It is possible to work around this limitation using unsafe_reset.

val ref : 'a -> 'a ref

ref v creates a new reference holding the value v. This operation runs in constant time, and has a very small (even negligible) overhead compared to Stdlib.ref. This function allocates one block of memory of three words (against two for Stdlib.ref).

val (!) : 'a ref -> 'a

!r returns the current value of r. This operation is constant time and has a negligible overhead compared to Stdlib.((!)). Moreover, it does not perform any memory allocation.

val (:=) : 'a ref -> 'a -> unit

r := v sets the value of the reference r to v. This operation has a very small overhead compared to Stdlib.((:=)) when no time has been saved with Time.save. Nonetheless, it is always constant time. Note that this function does not perform any memory allocation, except when the current “time” is accessible (or has not been collected) and r is being updated for the first time in the current “time”. If that is the case, two blocks of memory are allocated, for a total of six words.

val incr : int ref -> unit

incr r is equivalent to r := !r + 1.

val decr : int ref -> unit

decr r is equivalent to r := !r - 1.

module Time : sig ... end

The Time module provides an abstract representation of time, used to set a point from which updates to references are recorded to allow undoing (of redoing) the corresponding changes.

val pure_apply : ('a -> 'b) -> 'a -> 'b

pure_apply f v computes the result of f v, but reverts the updates to references before returning the value.

val pure_test : ('a -> bool) -> 'a -> bool

pure_test p v applies the predicate p to v (i.e., compute p v) and returns the result, reverting the updates made to reference if the result is false. Updates are preserved if the result is true.

val unsafe_reset : 'a ref -> unit

unsafe_reset r can be used to work around the marshaling limitations. In fact, there is no problem marshaling data structures containing references (i.e., values of type ref). However, unmarshaling such a value will leave it in an inconsistent state with respect to the library. Hence, it is absolutely necessary to call unsafe_reset on every element of type ref in an unmarshaled value. Doing so will make the system believe that the reference has just been created. Note that unsafe_reset should not be used in any other situation, and especially if the given r has already been updated with (:=).