[m-users.] if/then/else griping.

emacstheviking objitsu at gmail.com
Mon Jul 22 21:15:22 AEST 2019


Both beautifully expressed presented Julian, I feel your pain and I have
only been using mercury for a few weeks now.

I am a long time emacs hacker but I have become so fed up with trying to
make code look "right" that I have found myself using VSCode of all things
as it doesn't really do anything other than syntax colouring and leaves the
layout to me. I read a really old PDf on "Prolog style" and I am sticking
with that as far as it makes sense to do so with Mercury and, for all
intents and purposes I have abandoned "if-then-else" as I find the
"traditional" way completely readable, but I have a few years of Prolog
under my belt.

It's a never ending battle!

Sean.


On Mon, 22 Jul 2019 at 07:16, Julian Fondren <jfondren at minimaltype.com>
wrote:

> Hello,
>
> Please consider the following. I realize that daytype/1 would be
> better as just a bunch of disjunctions, but I'm using the example to
> show off different ways to format Mercury code:
>
>    :- type days
>        --->    sunday
>        ;       monday
>        ;       tuesday
>        ;       wednesday
>        ;       thursday
>        ;       friday
>        ;       saturday.
>
>    :- func daytype(days) = string.
>    daytype(D) = R :-
>        (
>            D = wednesday
>        ->
>            R = "humpday"
>        ;
>            (D = sunday; D = saturday)
>        ->
>            R = "weekend"
>        ;
>            R = "workday"
>        ).
>
> if/then/else seems to be the recommended style, but, I find it
> impossible to format in a pleasing way. Here are some attempts, and
> my problems with them:
>
>    % this feels like the natural way.
>    % but this is a level of indentation too many.
>    % it looks OK here but not next to (A;B;C;D).
>    daytype(D) = R :-
>        (
>            if D = wednesday then
>                R = "humpday"
>            else if (D = sunday; D = saturday) then
>                R = "weekend"
>            else
>                R = "workday"
>        ).
>
> vs.
>
>    % Mercury stdlib seems to have settled on this style.
>    % the initial 'if' looks unbalanced vs. the rest of the code.
>    daytype(D) = R :-
>        ( if D = wednesday then
>            R = "humpday"
>        else if (D = sunday; D = saturday) then
>            R = "weekend"
>        else
>            R = "workday"
>        ).
>
>    % trying to fix the previous version.
>    % new problem: inconsistent indentation.
>    daytype(D) = R :-
>        ( if D = wednesday then
>            R = "humpday"
>          else if (D = sunday; D = saturday) then
>            R = "weekend"
>          else
>            R = "workday"
>        ).
>
>    % trying to fix the inconsistency.
>    % new old problem: this is a level of indentation too many.
>    daytype(D) = R :-
>      ( if D = wednesday then
>          R = "humpday"
>        else if (D = sunday; D = saturday) then
>          R = "weekend"
>        else
>          R = "workday"
>      ).
>
> Even if horizontal formatting is generally discouraged as a
> maintenance hassle, Mercury styling uses it a lot (and somewhat more
> conveniently than normal since it's aligned to tab stops), and it
> just looks really, really nice, for code that's not going to change
> a lot.
>
>    daytype(D) =
>        (
>            D = wednesday               ->  "humpday";
>            (D = sunday; D = saturday)  ->  "weekend";
>                                            "workday"
>        ).
>
> With if/then:
>
>    % This is somehow intolerable. With punctuation it looks like math
>    % you'd write freehand on paper. Maybe that's why I like that
>    % version.
>    daytype(D) =
>        (
>            if D = wednesday                    then "humpday"
>            else if (D = sunday; D = saturday)  then "weekend"
>                                                else "workday"
>        ).
>
> *Syntax* issues with languages, I'd normally disregard as trivial,
> but I don't think *formatting* is trivial. Formatting is so
> important that
>
>    1. languages like Python, Haskell, Nim, make it meaningful.
>
>    2. languages like Go (gofmt), Ada (gnatpp), Elm, make it
>       automatic. You don't format your code; a code prettifier does.
>
>    3. JavaScript speakers like Douglas Crockford pretend that
>       automatic semicolon insertion is a scaaaary, spooooky
>       nondeterministic process that you can't trust with your code,
>       in order to persuade devs to always use semicolons even though
>       JS doesn't actually need them, because there are exactly *two*
>       minor formatting problems that come up if you avoid semicolons
>       as a rule.
>
>    4. ReasonML and Elixir are successful and popular 'languages' that
>       are just skins over existing languages that are somewhat
>       more annoying (Erlang string literals produce list(char) and to
>       avoid that you write uglier <<"blah">> binary literals; OCaml
>       has a toplevel/non-toplevel syntax distinction that people so
>       routinely fail to understand that you'll see unnecessary ;;
>       double semicolons all the time in newbie OCaml code).
>
> Maybe this is untrue, but my assumption for a while was that
> if/then/else was added to Mercury in the first place because people
> learning Mercury complained about formatting problems with the
> Prolog-style conditionals. This is odd as the new syntax retains any
> problem you'd have with the old syntax, but, even if people are
> aggravated by something, this doesn't mean they *recognize* what
> specifically they find aggravating. Maybe the formatting aggravation
> was always mis-explained as "words are easier to read than
> punctuation":
>
>    1. other languages use words rather than punctuation (true, but
>       irrelevant)
>    2. other languages don't need to parenthesize their conditionals
>       to mark where the conditionals end
>
> Maybe the water's long under the bridge, but an 'end' token
> instantly fixes the syntax in my view.
>
>    daytype(D) = R :-
>        if D = wednesday then
>            R = "humpday"
>        else if (D = sunday; D = saturday) then
>            R = "weekend"
>        else
>            R = "workday"
>        end.
>
> ...
>
> Well, having said all that, I've already realized that the
> unbalanced-if is what the stdlib is going with, so I'll try that and
> see if it eventually stops bothering me.
>
> I do think that the tutorial should reflect this style if that's
> what's recommended. Right now the tutorial has
>
>    fib(N, X) :-
>        (   if    N =< 2
>            then  X = 1
>            else  fib(N - 1, A), fib(N - 2, B), X = A + B
>        ).
>
> which is just...
>
> 1. an indention too many
> 2. the N =< 2 column isn't on a (4spc) tab stop. If fixed to lie on
>     a tab stop (for writing/editing convenience), it's excessively
>     indented and looks ugly.
> 3. that final 'else' looks bad and every other way to reformat it
>     looks much, much worse.
>
> And then later, a four-space indentation, followed by a three-space
> indentation for if/then/else keywords, followed by a two-space
> indentation for the body of the conditional:
>
>    main(!IO) :_
>        io.read_line_as_string(Result, !IO),
>        (  if
>             Result = ok(String),
>             string.to_int(string.strip(String), N)
>           then
>             io.format("fib(%d) = %d\n", [i(N), i(fib(N))], !IO)
>             main(!IO)
>           else
>             io.format("I didn't expect that...\n", [], !IO)
>        ).
>
> I actually like Mercury's syntax, and how the language looks
> overall. I was even happy to discover that the omnipresent
> parentheses are really just mathematical parentheses for
> grouping, and that this is valid (if inadvisable):
>
>    daytype(D) = R :-
>        (D = sunday; D = saturday),
>        R = "weekend";
>
>        (D = monday; D = tuesday; D = thursday; D = friday),
>        R = "workday";
>
>        D = wednesday,
>        R = "humpday".
>
> But I don't think anyone could read the tutorial, and try to
> recreate the examples as they're shown, and come to any other
> conclusion than that Mercury conditionals are very annoying to
> format. While reproducing the second example, in vim, I used visual
> block mode to delete a single space, rather than actually recreate
> that 3-space indent.
> _______________________________________________
> 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/20190722/2d98a3a8/attachment-0001.html>


More information about the users mailing list