In other words, gofmt showed that it's easy to write a pretty printer if you ignore line breaking and instead force everyone to accept long lines. This is not a particularly interesting, and certainly not revolutionary, result.
(Not coincidentally, I have similar concerns regarding this Go versioning proposal and lockfiles.)
You don't need to accept long lines as gofmt respects your own line wrapping. It's easy to write code that never exceeds the 80 character limit. The main annoyance in go is it's use of tabs, so you have to change tabs in everything to a reasonable amount of space.
As such, I think your complaints are misplaced. gofmt is not a pretty printer. It's designed to implement a single standard format—one which does not define a maximum line width—but nothing more.
Indent, by the way, allows for a maximum line length.
It may help if you decouple the goal (increased readability of code) and the action (application of a style to code). Pretty printers—and gofmt—apply a style to code. That is their only job; in a traditional pretty printer, you could configure a terrifyingly awful style of code, and it would apply it happily and correctly. The readability of that style is a subjective judgment to others, but this is in no way a concern of the pretty printer.
You may not like the style of code that Go uses. That is a perfectly valid viewpoint, and I encourage you to develop it as you see fit! It is also perfectly valid to criticize the style choice of having an undefined maximum line width.
The problem gofmt solves is not "how do we allow you to style Go code", but more specifically, the problem it solves is "how do we encourage the community to adhere to one style of code for Go?" And it is successful in that. It is obviously unsuccessful in applying a style that you find aesthetically pleasing—alas!
Also, I am afraid that I did not claim indent does not allow for a maximum line width! I said that indent (like other pretty printers) allowed you to define a style "with a specific indent level" and that "you could mix in your own preference for indent level".
It's not successful if everyone puts line breaks in different places. By punting on that problem, gofmt isn't enforcing one style of code.
A typical pretty printer has knobs and dials to control its output, for instance — gofmt has none.
gofmt was a revolutionary social achievement: it got a huge number of people to basically all format their code the same. That had never been achieved before; prior to Go doing it, I would not have even thought it would be possible.
(Obviously, not revolutionary in any sort of technical sense.)
Having the editor wrap lines is contrary to standard practice in pretty much every other language. It requires extra editor configuration for no real benefit other than making gofmt a shorter program. Besides, editors don't wrap lines as nicely as a good pretty printer can. Again, look at clang-format: the heuristics it applies in order to apply a maximum line width are very carefully thought out.
Though, Python does do a better job than many languages of providing style guidance (pep 8 iirc), and I don't really see people do wacky stuff like messing with where to put space around parens. &c.
Can't speak to Fortran.
Thinking about it, maybe languages like J or APL are always consistently formatted by being so dense there's no room for extraneous formatting?
But certainly for C-like languages I've used, just getting people on the same team to all use the same format was a struggle, much less the whole company, much much less the whole world.
So in that way, gofmt definitely feels revolutionary to me.
clang-format has really changed the game here. It's commonplace in large projects to run it on every commit.
There is a difference between C and C++ formatting and Go formatting, and it's that Go had gofmt from the start and has always had large social pressure to conform to it. Contrary to popular sentiment, I'm not sure that this is an unmitigated good, though. The reason is that clang-format was designed to mimic the existing style that emerges when programmers manually format code for maximum readability. This forced clang-format to consider comment formatting, line length, argument bin packing, etc. It had to be good, or else it wouldn't get use. On the other hand, because gofmt was guaranteed to get lots of use no matter what, there was less pressure for the result to be readable. This shows up in decisions like the lack of a line length limit.
Well, again, I personally don't think line limit should be part of the code style -- it's really handy to be able to split or not split emacs buffers and have the code spill out to take up the space, wrapping dynamically. If the code hard-wraps, you're just stuck w/ that single decision. It's annoying.
Regarding Go's style more generally: Yeah, my own personal pref would be much denser that gofmt, but I happily submit for the consistency.
I just don't think style really matters that much (within the realm of reasonable, which gofmt certainly is): the important thing is consistency.
(By the way, a nice side-effect of consistency: you can easily grep for a particular thing w/ confidence w/o having to try to take into account all the possible stylistic variations.)
We were using indent with CVS pre-commit hooks in 1999, hardly revolutionary.
but yeah, team style was definitely a solvable problem. global style, manifestly was not solved!
I also just happen to really like things neat a tidy.
Final minor nice thing about having a fixed style: you can grep with confidence, without having to try to encode stylistic variations in the regex.
gofmt imposes a single style on the entire go ecosystem, that's unusual as most previous formatters have lots of options, and allow different teams to adopt different styles (e.g. tabs vs spaces). Turns out it doesn't really matter what style you choose as long as everyone uses the same one, and long lines aren't a problem in practice.
Worse is better.
It's just a philosophical stance, and a rather totalitarian one IMHO.
I disagree on that - it makes it much easier to share code and to use code from other teams, and removes a whole area which people waste a lot of time on (bikeshedding formatting issues).
(Again, maybe line length doesn't matter much in Go, since lines generally don't get that long in Go, but for lots of other languages gofmt's choice would not be acceptable.)
Interestingly enough, I've never seen people bikeshed about code formating in a project using a style formater even if it is configurable. But everytime Go is talked about here on HN, there are many people complaining about gofmt not being configurable …
Let's say I have this program (which was goformatted):
package main
import (
"fmt"
)
// commenting...
// commenting...
func main() {
fmt.Println("hello", "world")
fmt.Println(
"hello",
"world",
)
}
And I had log.Print("test") at the end of main(): package main
import (
"fmt"
)
// commenting...
// commenting...
func main() {
fmt.Println("hello", "world")
fmt.Println(
"hello",
"world",
)
log.Print("test")
}
Then I run goimports to automatically update the import directive (goimports parses the source to build an AST, then modifies the AST, then reconverts it to source code): package main
import (
"fmt"
"log"
)
// commenting...
// commenting...
func main() {
fmt.Println("hello", "world")
fmt.Println(
"hello",
"world",
)
log.Print("test")
}
Everything is kept exactly as-is, except the added line "log" in the import directive. This round-trip mechanism is the main benefit of gofmt.