How do you prettify record type declarations?

This is the lazy way of typing a record data type declaration:

data PersonName = PersonName with 
    firstName : Text 
    middleName : Optional Text
    lastName : Text 
    namePrefix : Optional Text 
    nameSuffix : Optional Text 
        deriving (Eq, Show)

This prettified version looks much more professional:

data PersonName = PersonName with 
    firstName     : Text 
    middleName    : Optional Text
    lastName      : Text 
    namePrefix    : Optional Text 
    nameSuffix    : Optional Text 
        deriving (Eq, Show)

Do you do this every time by typing spaces, or tabs, or you have some tool / trick to do that automatically?

2 Likes

I personally prefer the first version. The prettified version looks nice at first. But then you add a new field and suddenly you have to realign and your diff is 10 lines instead of 1 line.

As a rule of thumb, if you change 1 line and that results in a diff with more than one line, it might be worth considering if you can change your formatting to avoid that. Imho the advantages of making changes easy to review are much larger than the readability benefits from alignment.

5 Likes

Good to hear that!

I completely agree with @cocreature’s practical arguments, but I also happen to find the first form easier to actually read. It’s less pretty to look at from afar, sure, but that’s rarely what I want to do with my code.

Generally speaking I’ll be reading one line at a time, and thus I want to be able to quickly see what the type of that one field is. It only takes one field slightly longer than the others for it to become a bit harder to make sure you’re reading the right line on the right:

data PersonName = PersonName with 
    longer_name_than_I_like : Text 
    short                   : Optional Text
    small                   : Text 
    prefix                  : Int 
    suffix                  : Text
        deriving (Eq, Show)

Maybe it’s just me, but I really don’t find all that inline whitespace helpful at all. It’s different when you have an actual table of values where the columns make sense, so I’m not claiming vertical alignment is always bad, but when what you want to represent is a sequence of lines, keep it as a sequence of lines, don’t arbitrarily turn it inot a table.

3 Likes

I agree with @cocreature and @Gary_Verhaegen! This question of alignment also applies to variant constructors. For example, I prefer this:

data MyVariant
  = FirstConstructor Int Int
  | SecondConstructor String Int
  | ThirdConstructor (Optional Int) String

Over this:

data MyVariant
  = FirstConstructor  Int            Int
  | SecondConstructor String         Int
  | ThirdConstructor  (Optional Int) String

Another thing to note is that with syntax is optional, and sometimes I find it nicer to use the older curly braces syntax from Haskell, again without aligning the type:

data PersonName = PersonName 
  { firstName : Text 
  , middleName : Optional Text
  , lastName : Text 
  , namePrefix : Optional Text 
  , nameSuffix : Optional Text 
  } deriving (Eq, Show)

Notice that the curly braces and commas usually go at the beginning of the line in Haskell-style, not at the end like in most programming languages! :slight_smile:

2 Likes

I like prettified code but agree with @cocreature and @Gary_Verhaegen

1 Like

I think what we need is a code formatter! :grinning: I believe it’s somewhere on our backlog.

1 Like

Yes, indeed, now I’m writing a Go program and I like how Go reformats code at every save.