profile
viewpoint

Ask questionsPlacement of comma for lists, records, tuples, function type signatures...

TLDR It is unreasonable to start putting commas at the end of lines.

There was a ticket already on this topic that was about making this configurable in #497

In this ticket, however, I am not proposing making ormolu configurable. This issue is about changing the default, because current formatting choice is vastly worse than what the defacto Haskell style is.

Of course, my personal preference plays a role in me opening this ticket, but I will put it aside and will show facts instead.

I have looked at arguments in the blogpost in favor of comma placement at the end rather that at the beginning:

Multiline pattern matching

While this popular formatting choice works in expressions, it’s a parse error if used in a pattern, because everything in a multiline pattern should be more indented than the opening parenthesis.

Multiline pattern matching in case statements is rather uncommon, especially when compared with popular formatting choice. I even had to google it in order to see what it actually means.

For anyone reading this here is an example. These two will parse:

bar :: Num a => [a] -> a
bar [ x
    , y
    , z
    ] = x + y + z
baz :: Num a => [a] -> a
baz xs =
  case xs of
    [ x,
      y,
      z ] -> x + y + z

But this will not:

baz :: Num a => [a] -> a
baz xs =
  case xs of
    [ x
    , y
    , z ] -> x + y + z

For the curious here is a ghc issue that tries to improve the error message about it. IMHO it would be better to fix ghc to support such syntax, rather than use it as an argument to change formatting style.

Trailing comma is now supported by ghc

module Foo 
  ( foo,
    bar,
  ) where

vs

module Foo 
  ( foo
  , bar
  ) where

Did you notice that we also add trailing commas where possible, for example, in export lists? Our ability to do this comes from a relatively new feature in Haskell—it helps with Ormolu’s goal of achieving minimal diffs too. If we try to remember where leading commas come from, Johan Tibell’s style guide comes to mind. The author said later:

"[…] I designed [Haskell style guide] to work with the lack of support for a trailing comma. If we supported a trailing comma my style guide would probably be different."

There you have it: GHC supports a trailing comma now, so it’s not unreasonable to start putting commas at the end of lines.

That argument works for exports only and we do lack trailing comma support, so Johan Tibell's design is still valid.

Coming from other languages

This style is also more familiar to programmers who come to Haskell from other languages.

I think this is the worst argument of all. We don't need to change the style that people used for decades just because other languages do it and new people are accustomed to it. Haskell is unique in many aspects and many of those aspects is what makes it very powerful.

Negative affects of comma placement

I really don't think that above arguments are strong enough to enforce the same style in all other places affected by that decision:

  • lists
  • records
  • tuples
  • derivation clauses
  • function class constraint list
  • super class constraints list

If we did have the ability to place trailing comma at the end of all of these, then it probably would not be such a big deal, just as Johan Tibell said. Because then the only downside is that we have to type an extra symbol per line and possibly adjust our eyes a bit. However trailing comma is not possible and it is unlikely that ghc will ever change that. It'll definitely never be adjusted for tuples, since trailing comma in tuples implies TupleSections.

The downside of this style without support for a trailing comma is significant IMHO, because it has a very negative impact on the git diff. Here are two sample diffs:

+++ b/haskell/ormolu-trailing-comma/classic.hs
@@ -8,6 +8,7 @@ lists =
   [ "It is often lists do not fit into a single line."
   , "We need to format them in a readable fashion"
   , "without compromising functionality."
+  , "Placement of commas at the end increases git diffs!"
   ]
 
 data Record =
@@ -15,6 +16,7 @@ data Record =
     { records :: String
     , are :: Bool
     , no :: Bool
+    , exception :: SomeException
     }
 
 myRecord :: Record
@@ -23,6 +25,7 @@ myRecord =
     { records = "Records are also suscpetible to trailing comma problem"
     , are = True
     , no = False
+    , exception = toException StackOverflow
     }
 
 
@@ -32,9 +35,11 @@ tuples ::
      ( String
      , String
      , VeryLongTypeNameThatCausesForTupleiInTheTypeSignatureToWrapAroundTooAmIRight
+     , Bool
      )
 tuples =
   ( "It is less common for tuples to not fit into a single line."
   , "However it does still happen"
   , AmIRight
+  , True
   )
+++ b/haskell/ormolu-trailing-comma/ormolu.hs
@@ -7,13 +7,15 @@ lists :: [String]
 lists =
   [ "It is often that lists do not fit into a single line.",
     "We need to format them in a readable fashion",
-    "without compromising functionality."
+    "without compromising functionality.",
+    "Placement of commas at the end increases git diffs!"
   ]
 
 data Record = Record
   { records :: String,
     are :: Bool,
-    no :: Bool
+    no :: Bool,
+    exception :: SomeException
   }
 
 myRecord :: Record
@@ -21,7 +23,8 @@ myRecord =
   Record
     { records = "Records are aslo suscpetible to trailing comma problem",
       are = True,
-      no = False
+      no = False,
+      exception = toException StackOverflow
     }
 
 data VeryLongTypeNameThatCausesForTupleiInTheTypeSignatureToWrapAroundTooAmIRight = AmIRight
@@ -29,10 +32,12 @@ data VeryLongTypeNameThatCausesForTupleiInTheTypeSignatureToWrapAroundTooAmIRigh
 tuples ::
   ( String,
     String,
-    VeryLongTypeNameThatCausesForTupleiInTheTypeSignatureToWrapAroundTooAmIRight
+    VeryLongTypeNameThatCausesForTupleiInTheTypeSignatureToWrapAroundTooAmIRight,
+    Bool
   )
 tuples =
   ( "It is less common for tuples to not fit into a single line.",
     "However it does still happen",
-    AmIRight
+    AmIRight,
+    True
   )

We clearly get one unnecessary line of diff for every place where we append an element at the end.

tweag/ormolu

Answer questions lehins

In this kind of discussion no argument of ultimate convincing power is possible

If I only knew that I would not bother wasting my time on this. I'll make sure not to make that mistake twice.

The simplest reason why this is not going to change is that it would cause a lot of reformatting in existing projects, which we do not want.

If I understand you correctly, you are saying that whatever wrong decisions you have made about formatting style will never be fixed. Moreover, without lack of configuration users don't even have a choice of opting in for a fix, they are simply stuck with those bad decisions. Does not seems like a good policy/design decision to me. But hey, who am I to complain at free software. I wish you all the luck with this project.

useful!

Related questions

No questions were found.
source:https://uonfu.com/
Github User Rank List