[m-users.] Determinism woes...

emacstheviking objitsu at gmail.com
Fri Jul 5 20:28:21 AEST 2019


OK, I read everybodies comments, read all the suggested links and I amended
my code to be like so:

:- pred char_type(char::in, chartype::out) is det.

char_type(Char, Type) :-
    (   if      Char = '(' then Type = p_open
        else if Char = ')' then Type = p_close
        else    Type = c_general
    ).

This works as desired and as expected which is great, but....understanding
why! I can see that by using the if-then-else that the final else clause
has no mention of Char, whereas before I had "Char = _"...    meaning that
multiple solutions where available. In the polog-mercury transition docs,
section 6 cuts and indexing it says:

Mercury allows if-then-elses to be written not just as ‘C -> T ; E’, but
> also as ‘if C then T else E’. In Mercury, an if-then-else prunes away
> either the ‘else’ goal (if the condition succeeded) or the ‘then’ goal (if
> the condition failed), but if there are multiple solutions to the
> condition, they will all be found on backtracking, and the ‘then’ goal will
> be executed for each of those solutions. By contrast, an if-then-else in
> Prolog prunes away all solutions of the condition except the first.


But I find this hard to decipher. I can see the equivalence between the two
expression forms, that's the easier part, but I am confused where it says
"but if there are multiple..." because if the if-the-else is syntactic
sugar...? But it says something about pruning away the else goal or the
then goal(s) etc. I think I nearly have it but I find my brain feeling like
trying to climba greasy pole at time and I really really want to understand
this.

All I seek is some clarification over why the if-then-else works as I
expected it too and I can assimilate that and move on!

Thanks again,
Sean.




On Fri, 5 Jul 2019 at 05:17, Julian Fondren <jfondren at minimaltype.com>
wrote:

> On 2019-07-04 17:46, emacstheviking wrote:
> > Thanks Richard!
> >
> > That is so obvious when you see it. I am thinking like a Haskell
> > hacker this evening for sure.
> > I changed it to "cc_multi" and it compiled ANd did what I expected /
> > wanted.
>
> It may do you what you want, but this is by accident. It is legal for
> the cc_multi version of your code to report that '(' is a c_general
> rather than a p_open.
>
> Consider:
>
> https://mercurylang.org/information/doc-latest/mercury_ref/Semantics.html
>
> Or this chapter of the Prolog to Mercury guide:
>
>
> https://mercurylang.org/information/doc-latest/mercury_trans_guide/Commits.html
>
> I don't know Prolog well at all, and wouldn't've benefited from that
> chapter since I'm not familiar with that pattern of cuts and a
> catch-all, but I've run into your exact problem of wanting to say
>
>    char_type(')', p_open).
>    char_type('(', p_close).
>    char_type(_, c_general).
>
> because functional languages with pattern-matching all do it in an
> ordered way that permits very similar constructs. This is probably
> what you meant by "thinking like a Haskell hacker" but even C's
> switch() statement permits this sort of thing. For Mercury you can try
> viewing your code through the lens of the strict commutative
> semantics.
>
> So when looking at that code, imagine
>
>    char_type(_, c_general).
>    char_type(')', p_open).
>    char_type('(', p_close).
>
> or
>
>    char_type(')', p_open).
>    char_type(_, c_general).
>    char_type('(', p_close).
>
> or
>
>    char_type('(', p_close).
>    char_type(_, c_general).
>    char_type(')', p_open).
>
> ...
>
> If any variation doesn't look like something you'd want, your original
> code isn't what you want either.
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20190705/678f098e/attachment.html>


More information about the users mailing list