[mercury-users] Modular data-abstraction and mostly unique modes.

Fergus Henderson fjh at cs.mu.oz.au
Wed Jan 7 14:10:43 AEDT 1998


On 06-Jan-1998, Henk Vandecasteele <Henk.Vandecasteele at cs.kuleuven.ac.be> wrote:
> 
> I would like to build a finite domain solver. And given the
> modules in Mercury I want to build an abstract type.
> 
> Unfortunately this seems incompatiable with Mostly unique modes.

It's not really mostly unique modes which are the problem;
the same problem arises with any use of complicated modes
for abstract data types.

The problem is that although you can have an abstract type, you can't
have an abstract inst or an abstract mode.  The reason for that is that
we couldn't find any way to make them work.  The original design did in
fact include abstract insts (and the parser includes support for them)
but during development of the compiler we found that the mode analyser
really needs to know what the corresponding concrete inst is in order
to do mode analysis.

> One of data-structures I want to hide is the array I use to carry 
> all information and where I'd like to perform destrcutive update.
> 
> I can define an abstract type:
...
> But I cannot define modes without giving implementation  details!
> 
> I would like to write:
> 
> :- module fd_solver.
> 
> :- interface.
> 
> :- import_module fstore.
> :- type fd_store.
> :- mode fd_store_muo :: free -> mostly_unique.
> :- mode fd_store_mui :: mostly_unique -> mostly_unique.
> :- mode fd_store_mdi :: mostly_unique -> mostly_dead.

That would not be quite right.
In general, you might want only part of the fd_store to be mostly_unique.
So you'd really like to use an abstract inst `mostly_uniq_fd_store'
to correspond to the abstract type `fd_store'.

	:- module fd_solver.
	:- interface.

	:- type fd_store.
	:- inst mostly_uniq_fd_store.  % abstract
	:- mode fd_store_muo :: free -> mostly_uniq_fd_store.
	:- mode fd_store_mui :: mostly_uniq_fd_store -> mostly_uniq_fd_store.
	:- mode fd_store_mdi :: mostly_uniq_fd_store -> mostly_dead.

	:- implementation.
	:- import_module array.

	:- type fd_store == array(global_data).
	:- inst mostly_uniq_fd_store = mostly_uniq_array(ground).

As you found, this can't be done, because you can't have an abstract inst.

The work-around is to just make the inst concrete, and document that
it is intended to be abstract.

	:- module fd_solver.
	:- interface.

	:- type fd_store.
	% :- inst mostly_uniq_fd_store.  % abstract
	:- mode fd_store_muo :: free -> mostly_uniq_fd_store.
	:- mode fd_store_mui :: mostly_uniq_fd_store -> mostly_uniq_fd_store.
	:- mode fd_store_mdi :: mostly_uniq_fd_store -> mostly_dead.

	/* THIS IS REALLY PART OF THE IMPLEMENTATION, NOT THE INTERFACE */
	:- import_module array.
	:- inst mostly_uniq_fd_store = mostly_uniq_array(ground).

	:- implementation.
	:- type fd_store == array(global_data).

> Which I don't like.

Yes, it's not the most elegant solution imaginable, I'm afraid.
But it's just inelegant, not unworkable.  The fact that the type
is abstract prevents anyone from making use of the implementation details.

Cheers,
	Fergus.

-- 
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 users mailing list