Skip to content

proposal: go/printer: don't reformat single line if statements #57645

Closed
@ianlancetaylor

Description

@ianlancetaylor

This proposal is mainly due to @bradfitz and likely others. It's similar to #33113 but we could actually choose to adopt it.

I'm not sure that this is a good idea

The proposal is to not format certain if statements if they are written as a single line. This will permit more concise code for certain common error handling patterns.

Consider these two functions. They are the same sequence of tokens, formatted differently. However, gofmt today will not change either of them.

func F1() {
	go func() { fmt.Println("hi") }()
}

func F2() {
	go func() {
		fmt.Println("hi")
	}()
}

This is because go/printer permits a go statement with a simple function literal that is written as a single line to remain on a single line.

We could apply a similar rule to if statements. Basically, if

  • an if statement is written on a single line, and
  • the body of the if statement is a single return statement, and
  • nothing in the return statement would normally be formatted on multiple lines (such as a composite literal), and
  • there is no else clause

then go/printer would not modify the if statement: it would remain on a single line.

Here is what the example from https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md might look like if this were permitted:

func CopyFile(src, dst string) error {
	r, err := os.Open(src)
	if err != nil { return err }
	defer r.Close()

	w, err := os.Create(dst)
	if err != nil { return err }
	defer w.Close()

	if _, err := io.Copy(w, r); err != nil { return err }
	if err := w.Close(); err != nil { return err }
}

In other words, this proposal would permit more concise error handling without changing the language. It would be concise not in the sense that it would use fewer tokens, or that it would require less typing, because it wouldn't, but in the sense that it would be less obtrusive on the page.

This proposal would not affect any existing code. It would merely permit people to use a different formatting style for this specific case, and gofmt would preserve that formatting style.

Of course, that is also a disadvantage, in that it would introduce a variation in Go formatting, one that is more significant in practice than the formatting of go and defer statements. One could imagine arguments about the formatting style to use, which would go against the goal of gofmt.

As I said above, I'm not sure this is a good idea, but I wanted to write it down for discussion purposes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions