[m-dev.] Module qualification of typeclass methods

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 16 01:35:27 AEDT 2001


To elaborate on my earlier response...

On 12-Nov-2001, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> 
> When `:- export_module' or `:- include' is being used to
> combine two modules, I think it's a bit ugly to have to
> know how the combined module was constructed.

You're right.  This is indeed a drawback to this proposal.
For reasons that I explained earlier, I think it is a very
minor one, but I agree it is a drawback.

> Instead, I would suggest allowing renamings, for example
> :- include bar where [pred x/1 is y].

You can achieve the same effect without language support
for renamings by writing an explicit forwarding predicate.
Likewise for functions.  And for types, insts, and modes,
you can define an equivalence using `=='.

Since IMHO the need to do this would be very very rare,
I think that is quite sufficient.

I think it's better to live with the drawback mentioned,
which I think will rarely be much of a problem in practice,
rather than complicating the language significantly in
order to solve it.

> I also don't like the idea of relaxing the restriction that
> there can only be a single predicate or function with a
> given name in a module. That every predicate or function
> has a unique fully qualified name without looking at the
> argument types is very useful for readability.

I hope I have convinced you on this now?
I seem to have convinced Pete ;-)

Just to reiterate, I'm talking about allowing *references* to be overloaded
with the same module qualifier, but *definitions* remain unambiguous
(at most one definition of a given kind, name, and arity in each module).

Note that in the presence of nested modules, references can
already be overloaded in this manner.
E.g.

	:- import_module foo, bar.
	:- import_module foo__bar.

	:- func f(int) = int.
	f(X) = bar__g(X).  % ambiguous: could be bar__g or foo__bar__g.
			   % The type checker will resolve it based on
			   % the argument types.

In some cases, significant contortions may be needed to resolve the
ambiguity.  For example:

	% continuing the example above...

	:- type t == bar__t2.  % ambiguous: could be bar__t2 or foo__bar__t2.

Here, if the user means foo__bar__t2, then they can
resolve the ambiguity by adding the `foo__' qualifier.
But if they meant bar__t2, then it's not so easy.
They'd need to define another module, e.g.

	:- module stuff_from_bar.
	:- interface.
	:- import_module bar.
	:- type t2 == bar__t2.

import that here, and then refer to stuff_from_bar__t2 instead of bar__t2.

It would be possible to solve this by having a special syntax for
fully-qualified names, e.g. something equivalent to C++'s "::bar::t2".
However, again the question is whether it is worth complicating the
language with some additional mechanism to solve a problem that really
doesn't seem to occur in practice.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list