Index: reference_manual.texi =================================================================== RCS file: /home/mercury/mercury1/repository/mercury/doc/reference_manual.texi,v retrieving revision 1.379 diff -u -r1.379 reference_manual.texi --- reference_manual.texi 15 Jan 2007 02:23:58 -0000 1.379 +++ reference_manual.texi 29 Jan 2007 07:41:42 -0000 @@ -937,13 +937,9 @@ condition and then-goal of the if-then-else expression, hence @samp{!:@var{X}} may appear therein. -There are three restrictions concerning state variables in lambdas: first, -@samp{!@var{X}} is not a legitimate function result, since it stands for two -arguments, rather than one; second, @samp{!@var{X}} may not appear as a -parameter term in the head of a lambda since there is no syntax for specifying -the modes of the two implied parameters; third, @samp{!@var{X}} may not appear -as an argument in a function application since this would not make sense given -the usual interpretation of state variables and functions. +Special syntax for has been introduced to simplify predicate and function mode +declarations for state variables (@pxref{Predicate and function mode +declarations with state variables}). @table @code @@ -2461,6 +2457,7 @@ @menu * Insts modes and mode definitions:: * Predicate and function mode declarations:: +* Predicate and function mode declarations with state variables:: * Constrained polymorphic modes:: * Different clauses for different modes:: @end menu @@ -2819,6 +2816,95 @@ The mode analysis algorithm annotates each call with the mode used. +@node Predicate and function mode declarations with state variables +@section Predicate and function mode declarations with state variables + +Type and mode declarations for predicates and functions that use state +variables (@pxref{State variables}) can be simplified. + +For instance, imagine a predicate +@example + :- pred foo(int::in, int::out) is det. +@end example +@noindent +that is typically called using a state variable, i.e. as @samp{foo(!@var{Var})}. +Without using the standard mode shortcuts, the predicate declaration would be: +@example + :- pred foo(int::(ground>>ground), int::(free>>ground)) is det. +@end example +@noindent + +Making use of the chain introduced by state variables where the final +instantiatedness of the first argument must match the initial instantiatedness of the +second argument, we can omit the intermediate instantiatednesses and declare the +type and mode of both input and output arguments at once: +@example + :- pred foo(!int::ground) is det. +@end example + +Note that the scope of the bang (@samp{!}) semantically covers both the type +and the mode declaration. If the type and mode declarations were to be written +separately, the bang would appear twice: + +@example + :- pred foo(!int). + :- mode foo(!ground) is det. +@end example + +The following table summarizes all defined @dfn{state variables modes}: + +@example +!(X) means X>>X, free>>X +!destructive means unique>>dead, free>>unique +!mostly_destructive means mostly_unique>>mostly_dead, free>>mostly_unique +!input(X) means X>>X, X>>X +!backward(X) means B, A if !(X) means A, B +@end example + +The most common state variable modes are thus: + +@example +!ground for ground>>ground, free>>ground which corresponds to modes in, out +!destructive for unique>>dead, free>>unique which corresponds to modes di, uo +@end example + +The @samp{!backward(X)} mode is intended for cases where the state variable +chain is used ``backwards'', i.e. with input argument being the second one and +output being the first. + +Same syntax can be used for state variables appearing as function input arguments: +@example + :- func bar(!int::ground) = (int::out) is det. +@end example +@noindent +with the function being called as e.g. @samp{Out = bar(!State)}. This syntactic +construction thus allows a pure account for defining and calling ``functions +with side effects''. State variables can not appear as the output argument of a +function because they in fact encode a pair of arguments. + +For convenience, if all normal (stateless) arguments to a function appear +without a mode declaration, the default @samp{in} mode is assumed for input +arguments and @samp{out} is assumed for the output argument. A function +declaration thus in most cases needs to mention only state variable modes. + +Lambda expressions (@pxref{Lambda expressions}) can also use the state variables modes defined here. +E.g. +@example +pred(!StateVar1::StateMode1, Var2::Mode2, ...) is Det :- Goal +@end example +@noindent +is equivalent to +@example +pred(!.StateVar1::InStateMode1, !:StateVar1::OutStateMode1, Var2::Mode2, ...) + is Det :- Goal +@end example +where @samp{InStateMode1} and @samp{OutStateMode1} are the modes for the +respective input and output arguments of the state variable +@samp{!@var{StateVar1}} given state variable mode @samp{StateMode1}. + + + + @node Constrained polymorphic modes @section Constrained polymorphic modes