Certain special cases require a module to have one or more mutable (i.e. destructively updatable) variables, for example to hold the constraint store for a solver type.
A mutable variable is declared using the ‘mutable’ directive:
:- mutable(varname, vartype, initial_value, varinst, [attribute, ...]).
This constructs a new mutable variable with access predicates that have the following signatures:
:- semipure pred get_varname(vartype::out(varinst)) is det.
:- impure pred set_varname(vartype::in(varinst)) is det.
The initial value of ‘varname’ is ‘initial_value’, which is set before the program's ‘main/2’ predicate is executed.
The type ‘vartype’ is not allowed to contain any type variables or have any type class constraints.
The inst ‘varinst’ is not allowed to contain any inst variables. It is also not allowed to be equivalent to, or contain components that are equivalent to, the builtin insts ‘free’, ‘unique’, ‘mostly_unique’, ‘dead’ or ‘mostly_dead’.
The initial value of a mutable, ‘initial_value’, may be any Mercury expression with type ‘vartype’ and inst ‘varinst’ subject to the above restrictions. It may be impure or semipure.
The following ‘attributes’ must be supported:
:- pred get_varname(vartype::out(varinst), io::di, io::uo) is det.
:- pred set_varname(vartype::in(varinst), io::di, io::uo) is det.
:- pred get_varname(vartype::out(varinst)) is det.
The ‘constant’ attribute cannot be specified together with the ‘attach_to_io_state’ attribute (since they disagree on this signature). It also cannot be specified together with an explicit ‘trailed’ attribute.
The Melbourne Mercury compiler also supports the following attributes:
For the C backends this attribute allows foreign code to access
the mutable variable as an external variable called ‘Name’.
For the low-level C backend, e.g. the asm_fast grades, the type of this
variable will be MR_Word.
For the high-level C backend, e.g. the hlc grades, the type of this variable
depends upon the Mercury type of the mutable. For mutables of the Mercury
types int, float, char and string, the
corresponding C types will be MR_Integer, MR_Float,
MR_Char and MR_String respectively. For mutables of any other
type the corresponding C type will be MR_Word.
This attribute is not currently implemented for the non-C backends.
The ‘thread_local’ attribute cannot be specified together with either of the ‘trailed’ or ‘constant’ attributes.
It is an error for a ‘mutable’ directive to appear in the interface section of a module. The usual visibility rules for sub-modules apply to the mutable variable access predicates.
For the purposes of determining when mutables are assigned their initial values, the expression ‘initial_value’ behaves as though it were a predicate specified in an ‘initialise’ directive.
:- initialise foo/2.
:- mutable(bar, int, 561, ground, [untrailed]).
:- initialise baz/2.
In the above example ‘foo/2’ is invoked first, then ‘bar’ is set with an initial value of 561 and the ‘baz/2’ is invoked.
The effect of a mutable initial value expression terminating with an uncaught exception is also the same as though it were a predicate specified in a ‘initialise’ directive.