[mercury-users] Pred defns

Peter Schachte pets at students.cs.mu.OZ.AU
Fri Apr 3 11:00:57 AEST 1998

Hi Fergus,

On Fri, 3 Apr 1998, Fergus Henderson wrote:

> `:=' would certainly be a good idea, especially given the issue with
> left-to-right ordering and `##'.  And `:=' would be enough for this
> particular case.  But '##' or some equivalent would still be needed
> in other cases, e.g.
> 	map__set(#map, Key1, Value1, ##map),
> 	map__set(#map, Key2, Value2, ##map)

It's not actually necessary, since you can always write

	map__set($map, Key1, Value1, M1), $map := M1,
	map__set(#map, Key2, Value2, M2), $map := M2

	set(Key, Value, $$map) :-
		map__set($map, Key1, Value1, M1),
		$map := M1.

	set_map(Key1, Value1, $$map),
	set_map(Key2, Value2, $$map)

or better still

	set_map(Key, Value) ::-
		map__set($map, Key1, Value1, M1),
		$map := M1.

	set_map(Key1, Value1),
	set_map(Key2, Value2)

if you want to allow inter-predicate threading (which I know you don't ;-). 
This might work nicely if there are many places in the code that update the
same thread. 

> What does your global variables package do for situations like that?

Actually, I did put in support for this.  It's even more desirable for
Prolog, since Prolog doesn't even have functions.  The syntax I chose, and
still don't like, is

	map__set($map, Key1, Value1, $:=map),

I would have preferred something like

	map__set($map, Key1, Value1, ($map:=)),

but that requires := to be both an infix and postfix op.  

> > In fact, the first assignment of a value to
> > thread x refers to it as #x, and the second as ##x, but they are really
> > doing the same thing.  I think they should look the same:  both should be
> > assignments.
> Well, the first one is just a unification; but an assignment would work
> equally well there.

I know.  I'm arguing that it's preferable because it's more consistent.  If
you allow inter-predicate threading, it becomes essential since unification
would be testing the incoming value.

> > Oh, one more thing:  how about replacing #x by $x and ###x by
> > $$x (a gratuitous change, but I think $x just looks better, and $$x is
> > suggestive of two $x's)?
> Perhaps "$", "$$", and "$`" for "#", "###", and "##".

I'd stay away from quotes if possible:  they just /look/ like they need a
mate.  I think I prefer $:=, even though I don't like it very much.  At
least it's mnemonic.

Let me press you on ### (or $$ or whatever).  Would you allow a ### term to
stand for a pair of arguments anywhere, or only in calls to predicates that
are declared to take a thread in that position?  I strongly prefer the
latter because I really don't like the idea of the same predicate appearing
to have different arities in different places.  But if you do adopt the
latter, how do you specify both the input and output value in a call, and
get the right mode?  This doesn't come up in Prolog, of course.  Eg,

	$stream = [....],
	parse($$stream, Value),
	$stream = [].		% make sure the whole input is consumed

You'd like this to invoke the parse((in,in), out) mode of parse/(2 or 3).
This can be achieved by using an eager unification scheduling algorithm for
threads:  as threads are being turned into distinct variables, move
unifications with thread variables to the front of the clause.  Your
scheduler will push them to the right place.  (I think there's a fair
argument for pushing all unifications back to the first place one of the
arguments is ground, since this may improve the choice of some modes, but
you've probably got a counterargument).

-Peter Schachte               | IBM is not a necessary evil. IBM is not
mailto:pets at cs.mu.OZ.AU       | necessary.
http://www.cs.mu.oz.au/~pets/ |     -- Ted Nelson 
PGP key available on request  | 

More information about the users mailing list