golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.92k stars 17.52k forks source link

proposal: cmd/gofmt: permit single line case and statement #66433

Open dsnet opened 6 months ago

dsnet commented 6 months ago

Proposal Details

Sometimes you have relatively simple switch statements that look like:

switch color {
case MintCream:
    return "#F5FFFA"
case Azure:
    return "#F0FFFF"
case AliceBlue:
    return "#F0F8FF"
case GhostWhite:
    return "#F8F8FF"
...
}

In terms of total lines, this can get quite long.

I propose that we modify gofmt to permit keeping the case expression and the following statement on the same line if the statement is also a single line.

Thus, the above can be written as:

switch color {
case MintCream:  return "#F5FFFA"
case Azure:      return "#F0FFFF"
case AliceBlue:  return "#F0F8FF"
case GhostWhite: return "#F8F8FF"
...
}

and gofmt won't try to rewrite into the expanded form. It will however, column align all vertically adjacent statements.

To be clear, I'm not proposing that gofmt rewrite existing expanded switch statements into the compact form, only that it avoid expanding it if the author deliberately wrote it in the compact form.

The benefit of this is increased readability and consistency:

As with any formatting change, this can lead to less readable code, but the at least this change allows the programmer to best decide what is most readable and not have gofmt expand the whole switch statement. It also avoids the temptation to use a map literal just because it is more compact.

ALTree commented 6 months ago

Previously: #57667.

ianlancetaylor commented 6 months ago

this can't get quite long

Did you mean s/can't/can/ ?

dsnet commented 6 months ago

Correct. Fixed.

richjyoung commented 5 months ago

It looks like this has come up a few times and there's a couple of points I would like to raise that don't seem to have been considered previously:

Single line case statements can be trivially sorted (alphanumerically) in a lot of text editors. This is useful for maintaining large lookup tables.

The linked previous issue suggested a switch is unnecessary for building lookup tables - https://github.com/golang/go/issues/57667#issuecomment-1374443595. If the lookup table holds references to functions, and those functions make recursive use of the lookup table, this causes a initialization cycle for lookup compiler error.

The cycle could be broken by reconstructing the lookup table on each recursion, but I would imagine that would incur a performance penalty.