Fergus' hack

Bart Demoen bmd at cs.kuleuven.ac.be
Wed Oct 1 17:13:37 AEST 1997


Fergus wrote:

> > I hope it is not recommended seriously
> 
> Why not?
> 
> Is it really that difficult to fathom?
> I thought it was reasonably straight-forward, myself.

It is reasonably straight-forward to understand what happens, yes.
But it is not the kind of programming I would like to see in a
declarative language, that's why I would call it a hack instead of an
idiom. It is very reaonable to want to implement two different modes
of the same predicate with a different algorithm, and if I am writing
a library predicate, I would prefer the user of my predicate not to
have to write the choice explicitly in the form of an argument -
having two different predicates , each for a mode is for me the better
alternative anyway to the extra subtyped argument - but the reality is
that Mercury doesn't offer support to do that. What I would like to
specify - declare if you want - is (a simple example)

	:- mode p(in,out) is det with_clauses [p(X,Y) :- somealgo ].
	:- mode p(out,in) is det with_clauses [p(X,Y) :- someotheralgo ].

According to the findings of the compiler about the instantiation of
the arguments of a call to p/2, the desired algorithm will be
activated. Now, this looks perhaps bad, because there is no guarantee
that somealgo and someotheralgo define the same relation between X and
Y, so that by reordering a call to p/2, the meaning of the program
might change. But adding the extra forward/backward argument to p
gives the impression that the same relation exists between X and Y in
both modes, while this is also not necessarily the case (and in
Fergus' example it wasn't, was it ?). More importantly, it shows (to
me) that declarative programming with modes (whether done with the
Fergus-hack, by defining predicates p1 and p2 for the two modes, or as
above) should be done in an environment that supports declarations (+
proofs, supplied by users, or derived by the compiler) about the
equivalence of e.g. p1 and p2, or somealgo and someotheralgo. That's
something a declarative language should support and encourage, not
tricky use of modes.


To end on a lighter note ... of course I tried the hack in a small
program and than had a look at the err file; here is part of the
program and part of the err file:


:- type ab ---> (a ; b).

:- inst a = bound(a).
:- inst b = bound(b).

:- pred f(ab,int,int).
:- mode f(in(a),in,out).
:- mode f(in(b),out,in).


f(Z,X,Y) :-
	(Z = a ->        %%%% this is line 31 in fergushack.m
	    Y is X + 1
	;   X is Y + 7
        ).

=============

fergushack.m:031: Warning: the condition of this if-then-else cannot fail.
fergushack.m:031: Warning: the condition of this if-then-else cannot succeed.

=============


:-)


Bart



More information about the users mailing list