Elm-format: Single-line case-expressions branches?

Created on 30 Jun 2018  路  8Comments  路  Source: avh4/elm-format

I noticed in the code for package.elm-lang.org that @evancz wrote a case-expression where each branch is a single line:

case model.page of
    NotFound session -> session
    Search m -> m.session
    Docs m -> m.session
    Diff m -> m.session

elm-format currently formats this as:

case model.page of
    NotFound session ->
        session

    Search m ->
        m.session

    Docs m ->
        m.session

    Diff m ->
        m.session

Is this an improvement? I found the former easier to understand because I could spot the pattern more easily. At a glance I could more quickly tell "ah, it's extracting the session in each branch."

There are many situations in which elm-format gives the author a binary choice: single-line mode or multiline mode. Should there be a similar choice for case-expressions? That is, allow authors to choose between a case-expression with all single-line branches (e.g. for "mappings" like the above), versus a case-expression with all multiline branches like we have today?

0.9 discussion

Most helpful comment

having multi-line alignment makes diffs weird. What if NotFound session becomes NotFound sess? The diff looks like this:

@@ -1,5 +1,5 @@
 case model.page of
-    NotFound session -> session
-    Search m         -> m.session
-    Docs m           -> m.session
-    Diff m           -> m.session
+    NotFound sess -> session
+    Search m      -> m.session
+    Docs m        -> m.session
+    Diff m        -> m.session

Every line changed because one changed. Is that OK? I can see both sides:

  1. when reviewing a PR, this would make it harder for me, personally. What actually changed? What's just line noise? The core question here: is it OK for elm-format to create noisy diffs? I'm inclined to say that it doesn't now, and shouldn't start to.
  2. when reading code formatted this way, it would make it easier for me to pick out patterns. This is where code formatting shines! The code is presented in a way I can understand easily, so I understand it easily.

All 8 comments

I'd also prefer using a single-line version in many cases. I'm re-implementing a Month to Int function and it's very long for an elementary transformation. It's the same as this:
https://github.com/rtfeldman/elm-iso8601-date-strings/blob/1.1.2/src/Iso8601.elm#L435-L472

The case statement (with 12 branches) is 35 lines expanded, whereas a single-line version could be just 13.

Another reason for this is that there are cases in the elm docs that don't get formatted as they're written in the docs:
image

Even better would be if the arrows lined up:

case model.page of
    NotFound session -> session
    Search m         -> m.session
    Docs m           -> m.session
    Diff m           -> m.session

I find this form much better for simple conversion functions generally, which there tends to be quite a few of in my code bases.

having multi-line alignment makes diffs weird. What if NotFound session becomes NotFound sess? The diff looks like this:

@@ -1,5 +1,5 @@
 case model.page of
-    NotFound session -> session
-    Search m         -> m.session
-    Docs m           -> m.session
-    Diff m           -> m.session
+    NotFound sess -> session
+    Search m      -> m.session
+    Docs m        -> m.session
+    Diff m        -> m.session

Every line changed because one changed. Is that OK? I can see both sides:

  1. when reviewing a PR, this would make it harder for me, personally. What actually changed? What's just line noise? The core question here: is it OK for elm-format to create noisy diffs? I'm inclined to say that it doesn't now, and shouldn't start to.
  2. when reading code formatted this way, it would make it easier for me to pick out patterns. This is where code formatting shines! The code is presented in a way I can understand easily, so I understand it easily.

Many diff tools, including GitHub's, will highlight changes on a character-level in addition to the line level. Not all that hard to see what's changed in that case, though definitely still noisier.

But even if/when that wasn't the case I think I'd prefer the noise and better formatting since I read raw code a lot more than I read diffs.

I'd rather optimise for reading, so having the arrows line up seems like the better option. Plus: pretty much every diff tool I've ever used has the option to ignore whitespace-only changes.

This would be great to have. It eases my biggest pain when writing Elm code, what I call "the explosion of simple case expressions."

I implemented this in my own fork of elm-format. The rules are very simple:

  • If _every branch_ of the case fits a single line, use the compact form shown by @rtfeldman.
  • If _one or more_ alternatives are multi-line, use the elaborated form _for the whole case expression_.

I used this to format my Elm Collage package. You can see the effect of this change on this big nested case expression and a simple let bindings.

Along the same lines, I implemented that _bindings with no arguments_ may be fitted on a single line. You can see the effect on top level functions and in let bindings.

P.S. Note that I also removed some newlines between case branches and let bindings. This is a whole different decision and should not be discussed in this issue I think.

Would love to see single line case expression. <3 But I'd rather not have them vertically aligned because that always makes for messy diffs.

(split off timjs's suggestion for top-level and let declarations to https://github.com/avh4/elm-format/issues/708 )

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahstro picture ahstro  路  4Comments

rtfeldman picture rtfeldman  路  4Comments

rtfeldman picture rtfeldman  路  4Comments

Janiczek picture Janiczek  路  5Comments

conradwt picture conradwt  路  8Comments