Prioritising breaking behaviour in swift-format

How much control does swift-format give the user over prioritising where line breaks are made, specifically in function declarations and calls? The only configuration I can see so far is prioritizeKeepingFunctionOutputTogether.

Currently I am seeing the following two things occurring. In a function declaration which only just goes over the line length the open parenthesis is pushed to a new line eg

func myFunc(longParameterName: Double, longParameterName2: Double) {
    ...

can become

func myFunc(longParameterName: Double, longParameterName2: Double)
{
    ...

For function calls that have a closure at the end the closure parameters are pushed onto a new line

myFunc(longParameterName: Double, longParameterName2: Double) { value in
    ...

can become

myFunc(longParameterName: Double, longParameterName2: Double) { 
    value in
    ...

Personally I would prefer it broke the function parameters across multiple lines in both of these situations. I don't see any configuration parameter at the moment I can set to indicate this preference.

2 Likes

I personally agree with you and prefer the style you described. I am not sure whether it should be a configuration option or a style change but I think it’s worth tracking as an issue in swift-format.

We should probably just make prioritizeKeepingFunctionOutputTogether do this even when there's no output. The idea behind that configuration setting was that it would keep what's between the function parameter list's closing parenthesis and the body's opening brace "glued" together:

func f(someLongSignature: SomeLongTypes) -> Result {
}

// without prioritizeKeepingFunctionOutputTogether:
func f(someLongSignature: SomeLongTypes)
  -> Result
{
}

// with prioritizeKeepingFunctionOutputTogether:
func f(
  someLongSignature: SomeLongTypes
) -> Result {
}

It looks like it doesn't do that when there is no function output (so it doesn't glue the ) { together), but I don't see why it couldn't. That seems like a straightforward change.

I recall at least one very early potential adopter of swift-format balking at situations where this might happen, because they felt that it wasted too much vertical space when the only thing that needed to be wrapped was the trailing closure bit (or in a similar case, the return type of a function signature). I personally disagreed (I don't think optimizing for vertical space should be a goal in an of itself) but that's how we ended up with some of the configuration options we have today.

Nowadays, I'm fairly unenthusiastic adding new knobs to make minor tweaks to satisfy everyone's personal preferences, especially in the line wrapping space. That's not because of any opinion I have about those preferences, but because the more knobs we have, I've seen how hard it is to ensure that they're all well-tested, especially regarding all of their combinatorial interactions. I think we'd be much better off if we just converged on a single style that everyone could agree that they hate just a little bit of, but that would require a more official position to be staked in the ground. Until (or if?) that happens, I'm not sure allowing every customization that people want will scale particularly well (and it would end up being wasted effort if we did decide in the future to provide a more opinionated formatter). It's an unfortunate catch-22.

4 Likes

There are also situations I've seen where the function returns something but the opening parenthesis is the only thing moved to a new line

public func myFunction(longSignature: LongSignatureType) throws -> Return {
}

becomes

public func myFunction(longSignature: LongSignatureType) throws -> Return
{
}

Are you certain the opening parenthesis for the function is being glued to the output type when prioritizeKeepingFunctionOutputTogether is set to true

I understand why you want to keep the number of configuration parameters to a minimum, but if that is the case I would prefer the formatting style decisions to come from an official swift team position rather than an early adopter who potentially doesn't even use swift-format anymore.

Now that swift-format is part of the toolchain, it makes it a lot more attractive as a formatting tool as you don't need to install another tool to do formatting and each release is tied to a particular release of swift. But at the same time I don't want to feel I'm taking a backward step to use what is in effect now the official formatting tool for swift.

3 Likes

They do still use it.

And I absolutely agree with the rest of this! That's why I tried to advance SE-0250 in the very early days. Unfortunately, that review was suspended because it was contentious and not likely to achieve any kind of consensus at the time. I would love to revisit this and make progress this time around—I personally think an opinionated style guide and formatter like gofmt is the right way to go, but I'm only a single voice in that discussion.

However, until any kind of official decision is made that might choose a specific direction to take, we have to make calls about what we think is realistic and feasible to support in a software project while keeping it maintainable.

3 Likes