[m-dev.] 0.13 release: op/3 syntax

Peter Schachte schachte at csse.unimelb.edu.au
Mon Mar 6 00:09:52 AEDT 2006


On Sat, Mar 04, 2006 at 02:47:48AM +1100, Mark Brown wrote:
> On 04-Mar-2006, Peter Schachte <schachte at csse.unimelb.edu.au> wrote:
> > in order to read a piece of code, you need to understand the
> > types, functions, and predicates it uses.  The operators are 
> > just one small part of what you have to understand
> 
> No, they are an entirely different kettle of fish.
> For functions and predicates, all you need to know is the meanings of the
> names.
> For operators, the context is important.  You need to know the relative
> precedence of an operator with respect to those around it.

> :- some [T] impure pred foo(S::in, T::out) is det => baz(T) <= bar(S).

Egads!  The left and right facing arrows here are cute, but not
terribly intuitive.  I agree operators don't help much in this case,
but perhaps a different operator design would have been more readable
(and avoided the need for parentheses).

I don't understand this declaration because I've never really
understood existential types very well, and I haven't used type class
constraints enough to really remember the syntax.  If I could be
bothered to read up on this, and assuming the intent is clear without
the parentheses, I could parenthesize it.  But without understanding
these things, I couldn't read it any better without operators:

   :-(some([T],impure(=>(pred(foo(::(S,in),::(T,out)),det),baz(T))),bar(S))).

I probably got it wrong, but the parens all balance.  Does that look
better to you?  Certainly not to me.  Now to read it you have to
carefully match parentheses and count arguments to see what's what.
With operators, the operators should tell you what's what (once you
understand the construct you're using).

The point I keep trying to make is that understanding a piece of code
requires understanding the constructs it uses.  If it is expressed
with operators, that's just one extra thing you need to know.  Of
course, that means using operators is a bad idea, unless they make the
construct look more natural or familiar or make it easier to read.
Let's face it, L1 ++ L2 ++ L3 just *looks* better than append(L1,
append(L2, L3)).  In fact, it's visually ambiguous:  maybe it should
be append(append(L1, L2), L3).  But that ambiguity is a good thing:
it doesn't make a distinction that makes no difference to the user.
(If the distinction does matter, the op declaration clarifies
immediately.)

The problem you seem to be worried about is when visual ambiguity does
matter.  With user-defined operators this can come up in two ways.
Firstly, I may define multiple operators to be used together.  In this
case, I carefully plan the precedences, associativity, and fixity so
that they work together naturally, and then document how to use them.
If I've done it well, the reader should be much better able to read
and understand the code than if I hadn't used operators.  If not, I
shouldn't have used operators.  If you didn't agree with this, you
wouldn't keep adding operators to Mercury.

The second way visual ambiguity may arise is when operators from my
new constructs are juxtaposed with builtin or other user-defined
operators.  Again this is something the designer of a suite of
operators should consider, particularly in choosing precedences.  They
should also document when parentheses will be needed.  Note, though,
that this rarely causes concern for the *reader*.  For example, if I
define the precedence of 'in' wrong, then

	X + Y in L

will cause a syntax or type error, so the reader won't usually see it.
When they do see code like this, there's really only one thing it can
mean, which is the interpretation they naturally leap to.  And in
those rare cases where types don't catch the confusion and the
documentation doesn't clear it up, then it's really not that hard to
look at op declarations.

Actually, this is one place where Prolog has an advantage.  You just
fire up Prolog and use display/1 to print out the term you're
concerned about.  It's miserable reading the term without operators,
but it is unambiguous if you're patient enough to match the
parentheses and count the commas.  Of course, if you weren't using
operators, you'd always have to do that.

-- 
Peter Schachte              The question of whether a computer can think is
schachte at cs.mu.OZ.AU        no more interesting than the question of whether
www.cs.mu.oz.au/~schachte/  a submarine can swim.
Phone: +61 3 8344 1338          -- E. W. Dijkstra 
--------------------------------------------------------------------------
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