[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