for review: store__new_cyclic_mutvar

Fergus Henderson fjh at cs.mu.oz.au
Thu Dec 11 18:54:40 AEDT 1997


Hi,

Anyone care to review this?

library/store.m:
	Add `store__new_cyclic_mutvar'.

	Also move the comment above new operators from the
	interface section into the implementation section,
	so that it doesn't appear in the Mercury library 
	reference manual.

Index: store.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/store.m,v
retrieving revision 1.8
diff -u -u -r1.8 store.m
--- store.m	1997/11/20 05:59:20	1.8
+++ store.m	1997/12/11 07:52:32
@@ -75,21 +75,26 @@
 :- pred store__set_mutvar(mutvar(T, S), T, store(S), store(S)).
 :- mode store__set_mutvar(in, in, di, uo) is det.
 
-/* 
-The syntax might be nicer if we used some new operators
-
-	:- op(.., xfx, ('<-')).
-	:- op(.., fy, ('!')).
-	:- op(.., xfx, (':=')).
-
-Then we could do something like this:
-
-	Ptr <- new(Val)	  -->	new_mutvar(Val, Ptr).
-	Val <- !Ptr 	  -->	get_mutvar(Ptr, Val).
-	!Ptr := Val	  -->	set_mutvar(Ptr, Val).
-
-I wonder whether it is worth it?
-*/
+	% new_cyclic_mutvar(Func, Mutvar):
+	% create a new mutable variable, whose value is initialized
+	% with the value returned from the specified function `Func'.
+	% The argument passed to the function is the mutvar itself,
+	% whose value has not yet been initialized (this is safe
+	% because the function does not get passed the store, so
+	% it can't examine the uninitialized value).
+	%
+	% This predicate is useful for creating self-referential values
+	% such as circular linked lists. 
+	% For example:
+	%	:- type clist(T, S) ---> node(T, mutvar(clist(T, S))).
+	%	:- pred init_cl(T::in, clist(T, S)::out,
+	%			store(S)::di, store(S)::uo) is det.
+	%	init_cl(X, CList) -->
+	%	    store__new_cyclic_mutvar(func(CL) = node(X, CL), CList).
+	%
+:- pred store__new_cyclic_mutvar(func(mutvar(T, S)) = T, mutvar(T, S),
+		store(S), store(S)).
+:- mode store__new_cyclic_mutvar(in, out, di, uo) is det.
 
 %-----------------------------------------------------------------------------%
 %
@@ -158,6 +163,7 @@
 	% Note that this requires making a copy, so this pred may
 	% be inefficient if used to return large terms; it
 	% is most efficient with atomic terms.
+	% XXX current implementation buggy (does shallow copy)
 :- pred store__copy_ref_value(ref(T, S), T, store(S), store(S)).
 :- mode store__copy_ref_value(in, uo, di, uo) is det.
 
@@ -211,6 +217,23 @@
 
 :- pragma c_code(init(_S0::uo), will_not_call_mercury, "").
 
+/* 
+Note -- the syntax for the operations on stores
+might be nicer if we used some new operators, e.g.
+
+	:- op(.., xfx, ('<-')).
+	:- op(.., fy, ('!')).
+	:- op(.., xfx, (':=')).
+
+Then we could do something like this:
+
+	Ptr <- new(Val)	  -->	new_mutvar(Val, Ptr).
+	Val <- !Ptr 	  -->	get_mutvar(Ptr, Val).
+	!Ptr := Val	  -->	set_mutvar(Ptr, Val).
+
+I wonder whether it is worth it?  Hmm, probably not.
+*/
+
 :- pragma c_code(new_mutvar(Val::in, Mutvar::out, S0::di, S::uo),
 		will_not_call_mercury,
 "
@@ -232,6 +255,22 @@
 	*(Word *)Mutvar = Val;
 	S = S0;
 ").
+
+:- pred store__unsafe_new_uninitialized_mutvar(mutvar(T, S),
+						store(S), store(S)).
+:- mode store__unsafe_new_uninitialized_mutvar(out, di, uo) is det.
+
+:- pragma c_code(unsafe_new_uninitialized_mutvar(Mutvar::out, S0::di, S::uo),
+		will_not_call_mercury,
+"
+	incr_hp(Mutvar, 1);
+	S = S0;
+").
+
+store__new_cyclic_mutvar(Func, MutVar) -->
+	store__unsafe_new_uninitialized_mutvar(MutVar),
+	{ Value = Func(MutVar) },
+	store__set_mutvar(MutVar, Value).
 
 %-----------------------------------------------------------------------------%
 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list