[mercury-users] Uniqueness modes etc

Ralph Becket rafe at cs.mu.OZ.AU
Thu Jan 8 16:14:57 AEDT 2004


Dr Mark H Phillips, Thursday,  8 January 2004:
> 
> Now suppose we want to "package up" this process for use by some other
> part of the program.  Ie we want a function which will take a starting
> point integer i, and will return something which provides the above
> process.  We could just return a pred of the form:
> 
>   :- pred changingf(bool, bool, int, int)
>   :- mode changingf(in, out, di, uo) is det.
> 
> with
> 
>   changingf(F_i, B, I, Idash) :-
>     F_i = not (B && (I `mod` 2)),   % not sure of Mercury syntax here
>     Idash = I `div` 2.              % or here
> 
> and require the user of changingf to put the initial integer in and
> thread the state changes manually as the process evolves.  But there
> is nothing stopping the user "messing" with the process.  Eg, inbetween
> calls to changingf, they could multiply the current I variable by 4.

The correct solution is to make your "state" an abstract type.  For
example:

:- module f.
:- interface.
:- import_module int, bool.

:- type f_state.			% An abstract type.

:- func new_f_state(int) = f_state.	% Initialise an f_state.

:- pred changing_f(bool, bool, f_state, f_state).
:- mode changing_f(in,   out,  di,      uo     ) is det.

:- implementation.

:- type f_state == int.			% An f_state is actually an int.

new_f_state(I) = I.

changing_f(A, B, I0, I) :-
	A = not (B && I `mod` 2),	% Or whatever...
	I = I0 `div` 2.

Now a user of module f can create an f_state, but cannot examine it and
can only manipulate it by calling changing_f/4.

> > The disadvantages of the nb_reference approach are that it uses impure
> > code.  This destroys the declarative semantics, makes the code more
> > difficult to reason about, inhibits compiler optimization, and in Mercury
> > requires any code which uses it to be explicitly annotated as "impure".
> 
> Is this only a temporary difficulty.  Ie will the compiler be able to
> handle this in a pure way down the track, or does this approach
> fundamentally require an impure implementation?

No, it's a show-stopping semantics problem.  A purely declarative
program should not be able to observe any side effects of its operation.
nb_references break this rule.

> A different question... if you have several different states evolving,
> is it better to have a single store evolving and several mutvars
> refering to separate parts of that store (ie the store acts as a sort
> of program heap containing separate bits of allocated memory) or is
> it better for each mutvar to have its own store, each evolving
> separately?

That's a design decision.  For instance, the latter arrangement would
make it impossible to accidentally use a mutvar from one store to access
a different store.

-- Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list