[m-users.] Idiomatic Mercury - if-then-else or (C->I;E)

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Nov 24 12:35:53 AEDT 2015

> You are right; there are lots of languages that wildly dissimilar
> syntaxes for conditionals. (And you didn't even show Lisp's
> syntax ...)

To think that I forgot to mention that "if" may
be spelled "," or "|", as in Haskell's

   abs x | x < 0  = negate x
   abs x | x >= 0 = x

which is of course related to GHC's (er, that's
Guarded Horn Clauses, which I'd expect Mercury
programmers to know something about, not the
Glasgow/Glorious Haskell Compiler)
  H :- G1, ..., Gm | B1, ..., Bn.
for which Parlog used ":".

> However, if you weigh languages by popularity, either in
> the general population of programmers or more personally
> in the population of the people working on the Mercury project,

I don't.  I have lived through
 - Fortran or COBOL being what everyone who mattered used
 - Algol being what everyone knew (but few used)
 - Pascal being what everyone knew
 - C being what everyone thought they knew.

The design of C contains a large number of things which
were known to be error-prone blunders at the time.

I expect any competent imperative programmer to
be able to read something like this at sight:

   %string(*) %function pname(%integer index)
      %if index >= long base %start
         %if index >= name base %start
            %result = itos(index - zero base) %if index >= short base
            %result = tostring(index - char base) %if index >= char base
            %result = name(index)_p name
            %result = itos(const(index))
         %result = errors

At sight.  (This is actual code taken from a Lisp interpreter.)
I expect said competent programmer to be writing such a language
within a week after meeting it.  And I don't expect said
competent programmer to be whining that it doesn't look like C.
(The actual rules about %start/%finish are rather tricky; to my
mind pointlessly so.  For that matter, the PL/I-like distinction
between %begin %end and %start %finish also strikes me as pointless.
You don't have to *like* something to read it.)

> there *is* a sort-of dominant syntax family  for if-then-elses,
> which is the syntax used in the Algol/Pascal/C/Java family.

The function above is written in IMP, which *is* a member of
the Algol family: Algol 58 -> Algol 60 -> Atlas Autocode -> IMP.
(You will note that C's "return" is spelled "%result =".  Or if
you are returning a pointer, it's "%result ==".)

I would certainly expect a Mercury programmer to learn
very quickly to read

mode amerge(?, ?, ^).

amerge([U|X], [U|Y], [U|Z]) <-
    amerge(X, Y, Z).
amerge([U|X], [V|Y], [U|Z]) <-
    U < V
  : amerge(X, [V|Y], Z).
amerge([U|X], [V|Y], [V|Z]) <-
    V < U
  : amerge([U|X], Y, Z).

despite the analogue of "if" being written with a ":".

Why would we even bother with Mercury if we seriously
thought Fortran '08, COBOL '02, or ECMAScript 6 were
the final word in what a language *should* look like?

You know that you know a programming language when you
understand it in terms of itself, not in terms of other

One thing I personally found helpful in learning Prolog
was aquaintance with Dijkstra's "A Discipline of Programming".
See http://www.cs.toronto.edu/~chechik/courses06/csc2125/p453-dijkstra.pdf
for a description of the notation. Briefly,
   if C1 -> B1
   [] C2 -> B2
   [] Cn -> Bn
evaluates the Ci in some non-deterministic fashion and
executes one Bi for which the corresponding Ci is true, and
crashes if no Ci is true.  
   do C1 -> B1
   [] C2 -> B2
   [] Cn -> Bn
executes one Bi for which the corresponding Ci is true then
loops, or stops if no Ci is true.  You will notice the use
of the arrow for "then".

When writing *algorithmically* tricky code in Prolog or
Mercury, I've found following the principles of "A Discipline
of Programming" helpful, and the correspondence between
Dijkstra's notation and ( -> ; ... -> ; fail ) also helpful.
I am not ashamed to say that Dijkstra's book *revolutionised*
my ability to solve problems I hadn't seen before (also
the Reynolds and Gries books of the same era).

I am *SICK* of the way we teach programming,
abandoning the hard won lessons of the past.

For a time I thought that programming-in-the-small was a
basically solved problem and that programming-in-the-large
was the big challenge.  But we are pressing on with
programming-in-the-large while reverting to the BL***Y
STONE AGE in programming-in-the-small.  Mercury is one of
a handful of blessed exceptions to that.  Semper floreat
et crescat!  (Dijkstra reference.)

More information about the users mailing list