A reference is essentially a persistent array of size 1. Given a viewtype VT, the type for references to values of viewtype VT is ref(VT). The type constructor ref is abstract in ATS, though it can be defined as follows:
typedef ref (a: viewt@ype) = [l:addr] (vbox (a@l) | ptr l)The interfaces for various functions on references can be found in the file prelude/SATS/reference.sats.
Reference Creation There is a function template ref_make_elt of the following type:
fun{a:viewt@ype} ref_make_elt : a -<> ref aGiven a value v of some viewtype VT, ref_make_elt<VT> (v) creates a reference of type ref(VT). For instance, the following code creates some references:
val r_int = ref_make_elt<int> (0) val r_double = ref_make_elt<double> (0.0) val r_fun = ref_make_elt<int->int> (lam x => x+1)There is also a function ref_make_view_ptr of the following type for turning pointers into references:
fun ref_make_view_ptr : {a:viewt@ype} {l:addr} (vbox(a @ l) | ptr l) -> ref aNote that ref_make_view_ptr is a polymorphic function; it is not a function template.
Reference Read and Write Given a reference r, the syntax for reading from r is !r and the syntax for writing (a value v) to r is !r := v. Note that in both SML and Objective Caml, the syntax for writing (a value v) to a reference r is r := v (instead of !r := v).
There are also two function templates ref_get_elt and ref_set_elt of the following types:
fun{a:t@type} ref_get_elt : ref a -<!ref> a fun{a:t@type} ref_set_elt : (ref a, a) -<!ref> voidwhich can used to read from and write to a given reference, respectively. As an example, we give a simple implementation of counters as follows:
// [int64] is the type for 64-bit integers in ATS typedef counter = '{ // the type for counter objects get= () -<cloref1> int64 // get the value of the counter , set= int64 -<cloref1> void // set the value of the counter , inc= () -<cloref1> void // increase the value of the counter , dec= () -<cloref1> void // decrease the value of the counter } fn counter_make (): counter = let // [int64_of_int] coerce an integer into a 64-bit integer val r = ref_make_elt<int64> (int64_of_int 0) in '{ // record creation get= lam () => !r // read from [r] , set= lam (x) => !r := x // write to [r] , inc= lam () => !r := succ !r , dec= lam () => !r := pred !r } end // end of [counter_make]
The code used for illustration is available here.