Skip to content

Formatting algorithm is somewhat unprincipled #1104

Description

@penelopeysm

Formatting output

Consider this:

julia> s = "f(x)"
"f(x)"

julia> format_text(s; margin=4) |> println
f(x)

julia> format_text(s; margin=3) |> println
f(
    x,
)

julia> maximum(length, split(format_text(s; margin=4), "\n"))
4

julia> maximum(length, split(format_text(s; margin=3), "\n"))
6

Ironically formatting with a smaller margin causes the text to fit on more columns! (And more lines to boot -- although that's "just" ugly, not unprincipled.) The reason is because JuliaFormatter sees "oh... we can't fit f(x) into three characters, so we'll indent the arguments". However, it doesn't then see that indenting the arguments causes it to become even worse.

In general, this is not easy to fix. (Like, sure, I could put in some code to catch the exact case above; but that will generalise poorly.) A proper fix for this would demand essentially a complete rethink of the formatting algorithm, which will have to be part of a big refactor. But in my opinion it may well be worth studying how other formatters deal with such issues before settling on a solution. I've been reading, e.g.,

but I'm well aware that probably the only true solution is to study the source code of other formatters.

In general though my belief is that the correct solution is to do some kind of search over a tree of all possible formatting options. This is what the two latter links above describe. In general this is exponential in the length of the text being formatted, but with some clever short-circuiting choices (again some are described in those links) this can be made tractable.

Idempotence

I also have some level of hope that having a more well-formalised formatting algorithm can fix idempotence issues. See the discussion on v2_stable_multiline_strings for more info.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions