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