I’m a -1 on this whole venture for several related but independent reasons:
The stated motivation is a non-issue
I don’t find it difficult to read Swift from unfamiliar projects — or rather, when I do, it’s rarely because of formatting issues.
I don’t find it difficult to adapt myself to per-project styles.
I don’t think this problem is worth the energy it will suck out of this community.
Experience with similar tools suggests standardization won’t work
In the pitch thread, many people praised Go and Rusts’s standardized formatting.
My own most extensive experience with enforced formatting has been Rubocop, and that experience hasn’t been lovely. Unlike Go and Rust’s formatters, Rubocop is extensively configurable — yet somehow still manages never to quite fit code on the projects that use it. Its formatting rules harm readability more often than they help, and I’m often forced to make a tradeoff between writing more confusing code or the littering it with inline ad hoc Rubocop directives. A GitHub search for inline RuboCop directives gives a sense of the many ad hoc adjustments people find necessary. Rubocop is a frequent source of complaints and wisecracks on social media.
Many teams do find Rubocop a useful tool. You’d be hard pressed, however, to find somebody in the Ruby community who thinks its defaults should be an officially endorsed universal default.
Is Swift more like Go and Rust? In terms of language features, yes. In terms of language style, however, it is closer to Ruby in two significant ways:
-
Swift has a high degree of plasticity. Like Ruby, Swift is a language that adapts to a wide range of uses and programming styles. Swift can look Java-like, ML-like, Objective-C-like, Python-like. IIRC, Chris Lattner has stated it is Swift’s explicit goal to be good for everything from systems programming to scripting to apps to code-as-configuration to ML to a beginner’s teaching language. Unlike Rust and Go, Swift projects encompass a wide array of underlying programming idioms. Its expressive flexibility is not an accident.
It is entirely reasonable to expect that different Swift projects that use different idioms will need different rules. A “lots of operators” functional reactive style will probably want different rules about line breaks, whitespace, and expression indentation than a TensorFlow project where operators mostly appear in equations.
(Edit: For comparison, I have worked with Elm and its autoformatter. It was pleasant. But Elm is an extremely narrow language with a narrow purpose — even a standard program structure. It doesn’t take many forms and many styles the way that Swift and Ruby do.)
RuboCop’s high degree of configurability is necessary in a language that takes so many forms. Swift formatting rules would need a similar degree of configurability to be widely adopted — but this undermines the stated motivation of the proposal.
The proposal’s stated goal is widespread consistency across projects. This requires two things: (1) widespread adoption and (2) narrow rules. In a language with Swift’s plasticity, these two are in conflict: any proposal that could encompass a broad enough range of Swift projects to achieve the stated goal would have to be so minimal in its rules as to undermine it.
-
Swift gained widespread adoption before its formatting was standardized. Because of the plasticity I mention above, I’d say this is a strength of the language. Even if you are inclined to see it as a weakness, however, it’s simply the fact that developers already have tastes and preferences around which it will be difficult to achieve consensus.
This is going to be a long, ugly slog. Which brings me to….
Forum discussion is a terrible way to decide style rules
We’ve all heard the jokes about swift-evolution’s frequent and extreme descent into bikeshedding. I certainly don’t have the stomach to wade through a 200-message chain about whether to put spaces after colons in type names. The proposed process will bring out the worst of swift-evolution — and the outcome will be determined by those few who are willing to participate in the forum at its worst.
If we do proceed down this path, I would strongly suggest that we:
- Use forum discussion only to nominate formatting questions, e.g. “spaces before/after colons in type names?”.
- Gather empirical data on how widely people use different possible style options for each question.
- Adopt only rules that meet some predetermined threshold in some sample set of projects.
So, for example: We nominate brace placement for standardization, and find that (say) 96% of Swift projects use K&R style, so that becomes a rule. However, we find a 60%/40% variation between var a = [String]()
versus var a: [String] = []
, we decide not to make a rule for it.
Open-ended forum argument sounds hellish to me. In a discussion, even a focused discussion, we will rediscover that Swift formatting is nuanced and difficult. I say re-discover because…
The proposal ignores prior art from the community
Want to know how nuanced and difficult Swift style is?
Ask @Erica_Sadun, who literally wrote the book on the subject. Have you read it? Read it. Note how many places she’s identified tradeoffs between alternate approaches instead of making a single universal recommendation.
Ask the authors of SwiftFormat and SwiftLint how many configuration rules they’ve had to add — and how many requests they get for more. They know from real experience how many conflicting demands the community will place on a formatter.
And, with all due respect, the proposal authors don’t. The fact that the proposal not only doesn’t explain how it is usefully different from SwiftFormat, but doesn’t even mention it, is a serious oversight. It even feels insulting. That’s not just about hurt feelings, though; it’s dangerous because…
Ignoring community prior art has a past record of causing harm
We have past precedent of a high-minded specification-first design-by-forum-committee tool ignoring existing open source projects: the Swift Package Manager.
SwiftPM addressed a real need — CocoaPods and Carthage are Xcode-dependent and don’t support Linux — but its approach of declaring itself the standard before it had been tempered through widespread real-world use was the wrong one.
SwiftPM is promising, exciting, full of interesting ideas. But I can’t use it in practice: it’s too immature, and doesn’t even support iOS development. There were already good, if imperfect, tools in the problem space. SwiftPM ignored them, to its detriment. I think in particular of the convoluted “pinning” debate, in which a tangled proposal and then a do-over proposal ended up arriving at nearly the exact same version locking strategy that CocoaPods, Carthage, and every other mature package manager in the world already used. The wheel reinvention by committee was painful to watch.
SwiftPM, the official package manager of Swift, despite its great promise, remains the least used — and least useful — package manager for Swift. It sucked the air out of CocoaPods and Carthage without usefully replacing them.
Let’t not make that mistake again.
This proposal is treading on community work with giant feet. It should instead study and learn from the work others have already done, and enhance — not awkwardly half-supplant — that work.