[mercury-users] Pred defns

Peter Schachte pets at students.cs.mu.OZ.AU
Tue Mar 31 12:31:52 AEST 1998


A bulk reply to several messages:

On Mon, 30 Mar 1998, Fergus Henderson wrote:
> I agree that the hidden argument proposals do make it somewhat easier
> to write code.  Only somewhat, mind you, since often you will still need to
> *examine* every part of the code to see that it threads the hidden arguments
> in the right order, even if you don't need to change it.

By this I assume you mean that you need to check that a certain thread has
the "right" value at the time you want to use it.  Sure, it only makes it
somewhat easier, as opposed to making it completely easier. :-b

> But my main criticism is that I think making it easier to add hidden
> arguments in this way often this comes at the expense of making the
> modified code harder to read.  Because the arguments are hidden, it is
> harder to understand the program's data flow.

Balancing this, it also does the opposite:  by removing many arguments from
your code, it makes it easier to see the important bits.  It depends on how
many threads you have.  I find that when there are more than about 2 or 3
pairs, or more than about 6 or 8 arguments, it becomes difficult to figure
out which is which.  This is compounded by the fact that calls span several
lines.  I just find such code difficult to read.  I have to actually /try/
to read the code, instead of taking it in at a glance.  I also have to count
arguments to see which argument in the call actually corresponds to which in
the clause head.  But maybe that's just me. 

There's also another advantage:  it gives a consistent name to the "same" 
thread across many predicates.  Normal code only does this by convention;
cross-predicate threading does it systematically. 

> In general improving writability at the expense of readability is not a
> good trade-off for languages other than those designed specifically for
> rapid prototyping

I agree completely.  But I don't agree that hiding arguments need do this. 
If pred declarations are augmented with mention of the threads they hide
(or better:  the global variables they use or modify) then I don't believe
on balance readability would suffer at all.


On Mon, 30 Mar 1998, Thomas Charles CONWAY wrote:
> I think Richard's point, and the point illustrated by
> SISAL is that the *right* thing to do is find a metaphore not just for
> the destructive assignments, but for the (for want of a better term)
> `algorithmic notion' that those assignments are encoding.

It's not really a matter of "destructive assignment" at all; we're not
really talking about modifying things.  What these various proposals want to
do is give a name to a *sequence* of values, rather than a single value, to
have a notion of the "current" element of the sequence, and to provide
access to elements of the sequence.  The need for this is made clear by the
way programmers choose their variable names, eg:

	write(This, IO0, IO1),
	write(That, IO1, IO2),
	write(Theother, IO2, IO).

This is much less clear if I write:

	write(Theother, IO2, IO),
	write(That, IO1, IO2),
	write(This, IO0, IO1).

Or, worse,

	write(Theother, InOut, InputOutput),
	write(That, IOState, InOut),
	write(This, IO, IOState).

As much as we may like the commutativity of logic, we as humans are just
/used to/ and comfortable with considering things in the order they're
written.  Refusing to use this to convey information seems silly.

> It may be that we don't have a good collection of such metaphores yet,
> but I really think that the right way forward is to try to find them,
> not to throw up our hands and use schemes that merely maintain the
> status quo.

Sure, and if you can come up with a good higher-order way to do threading,
I'd use it in preference to any of the proposed schemes.  Keep me posted.


On Mon, 30 Mar 1998, Fergus Henderson wrote:

> For example:
> 
> 	main(###io) :-
> 		print("Hello world\n", ###io),
> 		#x = 42,
> 		##x = #x + 1,
> 		print("42 + 1 =", ###io), print(#x, ###io).

More self-promotion, because Bart asked for it.

OK, let's look at this.  That "##x = #x + 1" line behaves a lot like an
assignment.  We can get rid of the need for ## by adding a more orthodox
looking assignment operator.  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.  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)?

	main($$io) ::-
		print("Hello world\n", $$io),
		$x := 42,
		$x := $x + 1,
		print("42 + 1 =", $$io),
		print($x, $$io).

This seems a bit more readable to me.

Notice, though, that print/2 always has $$io as its second argument;  it
probably always will.  So why make me write it all the time?  In this case
it's not so bad, because there's only one such argument, but when there are
several it does create an unnecessary opportunity to get them the wrong way
around.  So let's just drop them, but replace ":-" with "::-" to make it
clear that we're doing something funny.

	main ::-
		print("Hello world\n"),
		#x = 42,
		##x = #x + 1,
		print("42 + 1 ="),
		print(#x).

I think that is easier to write, read, understand and maintain than the
original. This is the syntax my global variables package supports.


-Peter Schachte               | Mr. Spock succumbs to a powerful mating urge
mailto:pets at cs.mu.OZ.AU       | and nearly kills Captain Kirk. -- TV Guide,
http://www.cs.mu.oz.au/~pets/ | describing the Star Trek episode _Amok_Time_ 
PGP key available on request  | 





More information about the users mailing list