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

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Nov 24 14:07:02 AEDT 2015

On 23/11/2015, at 10:15 pm, Mark Brown <mark at mercurylang.org> wrote:
> Yes, but I don't mean to claim that semantic constructs have any
> consistent representation in syntax, only that some pieces of syntax
> have consistent semantics across languages. If the syntax is `if ...'
> then `...' is virtually always the condition. Likewise `then' is
> followed by the affirmative code and `else' by the negative code.

I thought it was clear from what I wrote yesterday
that the *semantics* is not consistent from language to language.

In Haskell we have
   if c then t else f
In Clean we have
   if c t f
Neither of them has the same semantics as C's if statement or
?: expression.  C's if statement does not have quite the same
semantics as Fortran IF construct.  None of these has the same
semantics as SNOBOL's (yes, I still use SNOBOL occasionally)
    c :S(tlabel)F(flabel)
or Icon's if statement.  The semantics of #ifTrue:iffalse: in
Smalltalk are different again: that's a procedure name that can
be passed around and called dynamically, not something you can
do with C's (or JavaScript's) 'if'.  In Erlang, COBOL 85, and
IMP the thing that follows 'if' is not an expression and does not
have a storable value; those languages are not alone: Mercury is
the same (2.15.4 "Conditional expressions".)  In the Prolog world,
SWI Prolog has
  ( Cond ->  Then ; Else )     % "hard cut"
  ( Cond *-> Then ; Else )     % "soft cut"
Quoting the manual, "The control is defined as follows:
If Condition succeeds at least once, the semantics is the
same as (Condition, Action).  If Condition does not succeed,
the semantics is that of (\+ Condition, Else).  In other words,
if Condition succeeds at least once, simply behave as the
conjunction of Condition and Action, otherwise execute Else."
Now importantly, *Mercury's* ( Cond -> Then ; Else ) corresponds
to SWI Prolog's *->;  Manual 2.11 "Goals":
if CondGoal then ThenGoal else ElseGoal
CondGoal -> ThenGoal ; ElseGoal

An if-then-else. The two different syntaxes have identical
semantics.  CondGoal, ThenGoal, and ElseGoal must be valid
goals.  Note that the “else” part is not optional.

The declarative semantics of an if-then-else is given by
(CondGoal, ThenGoal ; not(CondGoal), ElseGoal), but the
operational semantics are different, and it is treated
differently for the purposes of determinism inference
(see Determinism).  Operationally, it executes the CondGoal,
and if that succeeds, then execution continues with the
ThenGoal; otherwise, i.e. if CondGoal fails, it executes
the ElseGoal.  Note that CondGoal can be nondeterministic
— unlike Prolog, Mercury’s if-then-else does not commit
to the first solution of the condition if the condition succeeds.

So the *semantics* of a conditional goal or expression in
Mercury are fundamentally unlike the *semantics* of an if
statement or expression in a C-family language.

At school I was taught to be aware of "faux amis":
French words that *looked* like English ones but
*meant* something different.

The semantics of a Mercury conditional are different from the
semantics of an Algol conditional, and you are in for a world
of pain if you forget this.  And coming to Mercury from Prolog,
I regard the clash of semantics between Mercury and Prolog as
the very best reason there is to avoid _->_;_ in Mercury,
unless you exercise constant trepidant vigilance to ensure that
tests have no more than one solution.

One final example of the cross-language consistency of semantics.
Imagine an 'if' construction in which
   if e1 then e2 else e3
can evaluate e1, then evaluate e2, and some time later wake
up again and execute e3.  Surely nobody would allow _that_?
ML and Scheme do!

Consistent semantics?  My left foot!

Yukihiro Matsumoto said
Everyone has an individual background.
Someone may come from Python, someone else may come
from Perl, and they may be surprised by different
aspects of the language.
Then they come up to me and say, 'I was surprised by
this feature of the language, so Ruby violates the
principle of least surprise.'
The principle of least surprise is not for you only.
The principle of least surprise means principle of
least MY surprise.
And it means the principle of least surprise
after you learn Ruby very well.
For example, I was a C++programmer before I started
designing Ruby. I programmed in C++ exclusively for
two or three years. And after two years of C++
programming, it still surprises me.

The way I'd put it is that you have to understand a
programming language in terms of itself.
If it's inconsistent with *itself*, that's a serious problem.
If it's inconsistent with some other language, not so much.

Thankfully, nobody has yet written a book called
"Mercury, the good parts."


More information about the users mailing list