gofmt will fix indentation, spacing, and so on, but it will generally preserve structure. For example, this:
a:=Foo{value:42}
becomes, of course: a := Foo{value: 42}
But! This: a:=Foo{
value:42,
}
becomes: a := Foo{
value: 42,
}
That's because gofmt can't really pretend to know that it knows better than the developer here. Sometimes code does need to be loose (like in a DSL or a big declaration, or a test (which must be readable), or similar). Sometimes it should be compact.This means you never have to fight gofmt. Never once have I disagreed with its decisions.
gofmt works this way because its ruleset isn't exhaustive; it says that, yes, an indent must happen after a hanging "{", but the ruleset doesn't say that a line break must happen. If there's a line break, let's stick with it.
Prettier seems to have a strict normalization approach: AST goes in, canonical form goes out. For example, I tried this fictional piece of code:
performAction({
type: "thing",
value: 42,
owner: user,
bucket: root,
path: p
});
It's turned into a much less readable blob because it happens to fit on a single line: performAction({type: "thing", value: 42, owner: user, bucket: root, path: p});
Unfortunately, in every instance where I indent the code in this manner, it's for a specific reason. I wanted it on separate lines; the fact that it happens to fit on a single line doesn't matter at all. Prettier overruled my carefully indented code.I often format code in a specific way for regularity: Every chunk in a block should have the same format, because each chunk is an instance of the same pattern. For example, I might have something like:
const RULES = [
{
type: "boost",
fn: node => increaseImportance(node),
weight: 0.5,
dependencies: ["priority", "rotation"]
},
{
type: "eliminate",
fn: node => nil
},
// ... lots of rules ...
]
Prettier's output generates inconsistency: const RULES = [
{
type: "boost",
fn: node => increaseImportance(node),
weight: 0.5,
dependencies: ["priority", "rotation"]
},
{type: "eliminate", fn: node => nil}
];
To quote the immortal Trump: No way!Maybe one could use some advanced heuristics to find an optimal balance between width vs. indentation vs. compactness; for example, in the above array, a clever formatter could see that it's an array of object literals, which means that it should prioritize regularity over compactness. If it's an array of something simple (like numbers, but not numbers with trailing comments), it can go compact. Maybe.
I don't use Prettier at the moment, but I know the strictness would drive me nuts. I predict that Prettier is going to cause a lot of frustration and heated discussion as a result of the one-size-fits-all approach. I don't think a canonical form for everything even makes sense; people need regularity (and no surprises), but not at the cost of readability.