Pitch: an Official Style Guide and Formatter for Swift


(Tony Allevato) #1

Hey all, I'm very excited to bring this pitch today to get more feedback from the community—it's an effort that my team at Google has been doing in collaboration with @dabrahams (co-author) and many other folks on the Swift team.

SE pull request.


An Official Style Guide and Formatter for Swift

Introduction

We propose that the Swift project adopt an official style guide and provide a formatting tool that lets users easily diagnose and update their code according to those guidelines.

Motivation

At the time of this writing, there is no single style agreed on by developers using Swift. Indeed, even Apple's own Swift projects on GitHub—such as the standard library, Foundation, Swift NIO, and so forth—have adopted their own varying styles. Furthermore, in many cases the code in those projects—despite the owners' best efforts—is not always completely consistent in terms of style.

In the absence of strict language-specific guidelines, many organizations adopt company-wide or project-wide style guides, which other developers may, and do, choose to adopt. But going further than that and having official style guidelines from the language owners and community themselves, along with tooling that enforces those guidelines, provides a number of additional benefits:

  1. The guidelines serve as a clear and easily referenceable source of language best practices and patterns, rather than developers trying to glean these by reading existing code.
  2. Developers can move from one codebase to another without incurring the mental load of learning and conforming to a different style or being required to reconfigure their development environment.
  3. Developers spend less time worrying about how to format their code and more on the program's logic.
  4. Likewise, code reviewers spend less time commenting on code formatting issues and more on its logic and design.

The first two points in particular align well with the Swift team's goal of making the language easy to learn. They also remove learning barriers for developers who want to contribute to a new open-source project, or to the language itself.

Proposed solution

This proposal consists of two parts, discussed below:

  1. We propose that Swift adopt an official style guide for the Swift language.
  2. We propose formally adopting a formatting tool into the Swift project that will diagnose and fix violations of that style.

Style Guide

This meta-proposal does not attempt to define any specific style guidelines. Its purpose is to answer the following existential question:

Should the Swift language adopt an official style guide and formatting tool?

If the answer to this is "yes", then a subsequent proposal will be pitched to discuss and ratify an official style guide.

Formatting Tool

If the proposal is accepted, the Swift project will adopt an official code formatting tool. The adoption of such a tool into the Swift project will not preclude other similar tools being written, but the expectation is that this tool will be officially maintained as part of the Swift project and will (once the details are decided) enforce the official style guide.

The proposal authors (among others) have collaborated on the swift-format tool currently hosted at https://github.com/google/swift/tree/format and intend to propose its adoption into the Swift project.

The tool will be used as part of evaluating options for an official style guide, as part of a follow-up proposal on the details of the style guide itself.

Alternatives considered

One alternative would be to not bless an official style and leave it to individual developers and teams to create their own guidelines (if they so desired). That, of course, does not address the points listed in Motivation above.

Some Swift users have suggested that instead of having an official language style, tooling should be able to transform code to the developer's personal style upon checkout and then back to some canonical style upon check-in, allowing individual developers to code in whatever style they wished. While such ideas are intriguing, we find them to be more of an academic curiosity than a practical solution:

  • Varying personal styles would hinder team communication. Team members should be able to discuss code on a whiteboard without it looking foreign to other people in the room, and to make API and language design decisions based on a clear idea of how the code will look.
  • This approach assumes that all tools on all platforms used in the developer's workflow support this approach. The development experience would suffer if the code does not use the same format locally as it does on their code review system, or if remote builds reported errors at different line numbers because they used a checked-in snapshot with a different style.
  • If the source of truth of the source code is saved in some canonical format and transformed when checked in/out, then there must still be some decision about what that canonical style is.

Indeed, nothing in this proposal would prevent a developer from using a workflow like the one described above, if they wished to implement it.

Acknowledgments

We gratefully acknowledge the following contributors, without whom this work would not have been possible:

  • the other contributors to swift-format: Austin Belknap (@dabelknap),
    Harlan Haskins (@harlanhaskins), Alexander Lash (@abl), Lauren White (@LaurenWhite), and Andrés Tamez Hernandez (@atamez31),
  • Argyrios Kyrtzidis (@akyrtzi) for his insight and help on using SwiftSyntax,
  • and Kyle Macomber (@kylemacomber), who advocated for using results of existing research for swift-format's implementation and found the Oppen paper, instead of inventing solutions from whole cloth.

[Style] Explicit self when referencing instance member
(Jon Shier) #2

I would say Swift shouldn't have an official public style, just one that all official Swift projects should adhere to. I don't believe any attempt to set a public style guide will be successful.

+∞ to an formatted integrated with SPM (and hopefully a commitment from Apple to integrate it with Xcode).

Before settling on swift-format, I would like to see a comparison to the capabilities of SwiftLint and SwiftFormat, given their popularity in the community. In particular, I don't believe a tool should be standardized if it can't be easily and informally extended for new rules as SwiftLint can be. AFAICT, swift-format has no ability to take plugins or rules defined in its configuration file. Any official tool must support both of those capabilities. Otherwise we're stuck with clang-format all over again.


(Keli C Fancher) #3

Yes, 100 times yes!

I'm tired of endless style debates and inconsistent styles across various projects. Of course I have my own opinions on how things should be formatted and I'm sure I wouldn't agree with every decision in an official style guide - but I'd be more happy with an officially sanctioned style guide and formatting tool then the current situation.

gofmt is one of my favorite things about Golang, it completely removes the need for style discussions in most cases.

Sure, there will be some instances where an official style guide will have to be ignored (such as in book publications and the like where page layout plays a larger importance) but in most cases I think this would only be a benefit.


(Tony Allevato) #4

Can you elaborate on why, beyond the fairly obvious fact that style is very subjective? Other languages, possibly most notable Go, and possibly Python to some degree, have had success with an officially blessed language style. I would imagine that 0% of people will be happy with every part of any official style guide that could be devised, but I don't think that's necessarily a reason to not attempt to do so.

I'm also not sure a distinction between an "official style guide" and an "official style guide for Swift projects" is too meaningful a distinction, since nobody would be forced into using a particular style or into running the formatter on their code (at least, we're not proposing that). The main project adopting a style for its own code is in effect a "soft" adoption of a style guide because others would gravitate toward it as a source of authority regardless.

swift-format is still a work in progress, which is why we're pitching it now and looking for feedback like this. We do have more extensibility in the works, though it hasn't been implemented yet; the "phase 1 pipeline" as we call it (the SwiftFormatRules module) is where custom rules would be written as syntax visitors, and we intend to add logic to enable/disable rules in the configuration shortly—so your concerns there will definitely be addressed.

Aside from that, swift-format has been implemented from day one with the desire to contribute it to the main Swift project in mind (that is, it has no outside (non-Apple) dependencies), and is built on top of SwiftSyntax so that it can take full advantage of the language parser and syntactic structure. To my knowledge, SwiftLint and SwiftFormat (at least their latest releases) are still relying on SourceKit or other parsing methods.

Of course, competition is very healthy and we don't want to preclude anyone else from working on tools of their own! But we do strongly believe that it's important for there to be something that is an officially maintained part of the project that can be integrated with other parts of the development workflow with ease, especially for newcomers to the language.


(Lance Parker) #5

Should there be an official style? Yes.
Should there be an official formatting tool that enforces this style? Yes.

Having one canonical style and an official formatter has been extremely successful for Go, and I would love to see something similar for Swift.

Having an official public style and a tool that enforces that style has many benefits. (All these assume the style and formatting tool are widely adopted by the community)

  • It puts an end to the inevitable "what should our style guide be" debates that tend to arise among team members
  • It makes reading code easier whether that be online (blog posts, Github repositories and pull requests) or locally much easier since it's in a consistent, familiar format.
  • Reduces context switching when switching between files of varying style.

I would prefer to see a formatting tool with minimal (or preferably zero) configuration options. A linter should be a separate concern from this formatting tool.


(Daniel Duan) #6

I'm 100% in favor of having an official style guide. I shudder to think of adding up the amount of time/energy/money a large team spends in pull requests just re-enforcing style guides. And the occasional discussions of such style guides are soul crushingly unproductive.

The next position I take might seem a little extreme: I think any one style guide that can be reliable enforced by a formatter is good enough. I'm talking about 3 spaces and a tab for indentation (okay, might be a stretch, there's limit). The core value a style guide provides is consistency. And I think the amount of collective time that the entire community can save from not having a style discussion anymore is so enormous that adapting to little details is a worthy sacrifice.


(Marcin Krzyzanowski) #7

Should the Swift language adopt an official style guide and formatting tool?

I thought it already did.

There is an unofficial/official style that is part of Swift code base: https://github.com/apple/swift/blob/master/lib/IDE/Formatting.cpp That's the style used by Xcode.

Companies (People in general) tend to be quite opinionated about style, and even invest in building tools to format code in one way: https://github.com/google/swift/tree/format. Others use tools like https://github.com/nicklockwood/SwiftFormat and adjust what they like.

That said, in my opinion, the current formatting (by SourceKit) is neither great nor bad - it can be disputable if it should be changed (flame war ahead). Personally, I don't care - everyone who disagrees with the SourceKit formatting may use whatever they want, and I think there are tools to help with that.


(Jeff Kelley) #8

I’m ambivalent about any official style guide, but there are certain circumstances that add constraints to code formatting where an official style might not be 100% compatible that give me pause. For instance, some book-publishing technologies I’ve worked with have a hard cap at 84 characters per line. Working with some HealthKit constants required some acrobatics to get everything to work with that line-length constraint, and if an official Swift style were not conducive to this scenario, we’d have to choose between rewriting the publishing tools and having Swift source code that looks wrong in the books.


(Tony Parker) #9

I don't think Swift should have an official style guide. I think Swift should provide a style guide "library", and tools to integrate the style of your choice in your project.

The Swift API guidelines were an effort to standardize the interface between various libraries and apps (including between the Apple SDK and others). Style, in my opinion, is an implementation detail of a library or app.

Each project deserves the flexibility it needs to determine for itself what kind of style is important to it. That could include factors like developer spoken language, outside tooling (e.g. code review systems that do not allow line wrap), interaction with other styles from languages used by that team, and more. Put simply: it feels completely out of scope for the language to define a hard rule about what will work for everyone in this case.

However, if we take the library and tooling approach, then teams can pick & choose, or customize, the rules that they need and move much faster towards an agreed approach that works for them.


(Argyrios Kyrtzidis) #10

This is only providing indentation, which is only a subset of what a style guide encompasses.
The proposed style guide and formatter tool would include rules beyond just indentation; just to provide a couple of examples:

  • How should a function declaration be re-formatted if it goes beyond a certain column limit
  • Should the opening brace of an if statement go on the same line or the next one

These are not things that the code you pointed at is handling.


(Ling Wang) #11

Finally! So tired of wasting time on style fighting. Just give us a single style and a formatting tool to enforce it, and everyone codes on consistently forever.


(Joe Fabisevich) #12

In my humble opinion gofmt is one of the best non-language programming improvements of the last decade. All of the styling holy wars died by the wayside, and the community is better for it.

While my initial reaction felt that an official style guide seems superfluous considering there aren't many stylistic debates in Swift, but if it means having an official formatter from the Swift team then I vote a huge +1 to having an official style guide.


(Jon Shier) #13

I suppose it mostly depends on what sort of formatting can be applied. No project I've ever been on has spent time debating spaces vs. tabs or brace placement, or anything else for Swift. How to handle empty lines is as close as it's gotten. It all revolves around naming conventions, class vs. struct, nest types vs. global, etc. An automatically applied style won't help with those conversations. So I question the value of what will likely be a contentious debate just to come up with the most basic rules.

An official Swift style guide along the lines proposed is "what you should use for your project". An official Swift core libraries style guide is merely a "what you can use for your project". There's less of a recommendation in the second option. Unless the core team is willing is diverge severely from the existing library style for the common one, either the common style won't be accepted there, which reduces the value of the standard in the first place, or it will and the common style will be similar, which IMO wouldn't be good.

I agree, it just seems likely those tools could've been used as a starting point rather than creating something from scratch, since it doesn't seem like swift-format will offer any unique capabilities. I don't think it serves the community to further branch tooling like this. For example, your desire to have no outside dependencies (is there an official rule here?) means that only JSON (or XML) rule files could be supported, given the paucity of formats supported by Foundation. Whereas the community has many hours invested in writing and building tooling for YML configurations, which swift-format can never support.


(Tony Allevato) #14

I'm glad that you brought this point up, because it's one that's a high priority for me as well. At Google, our Objective-C style guide specifies a column limit of 100 and an indent of 2 spaces. So, when we created our Swift style guide, the only realistic option was for us to use 100 columns and 2 space indent there because it's not possible to create language-specific line length and indentation settings in Xcode. You can have global settings and per-file settings, but not the medium that you actually need.

So as you point out, for Google developers, if Swift adopted a style with anything other than +2/100, that would be painful for us. Does that mean we should try to force everyone else to use +2/100? Of course not, because that wouldn't work for others.

So, the "library of styles" is something that I absolutely appreciate. Is your concern then that the term "official style guide" would impose One Line Length And Indentation To Rule Them All™, and would your opinion change if teams had the flexibility to make certain adjustments to fit their unique needs?


(Marcelo Fabri) #15

+1

I'd love a tool that is configurable and extensible (so a team could also write their own rules).

That said, Xcode support is fundamental for this. One of my main issues with the existing formatting tools is that they run outside Xcode, breaking undo and redo.

It'd also be great to have it somewhat independent from the compiler, as the official compiler release cycle is too long for small bug fixes and improvements. Being able to select the formatter the same way we can select a toolchain on Xcode would be ideal.


(Jon Shier) #16

Agreed, Xcode is the biggest issue here. In addition to supporting the tooling at all, it should support easy download and install of code styles from a library (in addition to syntax highlighting themes, snippets, templates, and plugins), and SPM can be integrated with such a service as well.


(Marcin Krzyzanowski) #17

definitely. As much as I agree on tooling (however, there are tool already and need for "the only one and right" swift-format does not appeal to me). I'm not in favor of "official style". Google did that already: https://google.github.io/swift/ why not just use it? (just kidding, this is how the holy war will begin - and this will happen).

The style guide is more like devpub domain, where it is actually important to have consistent style in books and tutorials.


(Byaruhanga Franklin) #18

Should there be an official style? Yes.
Should there be an official formatting tool that enforces this style? Yes.

Consistency & Readability matters, thus having an official style guide and the tools that help automatically enforce the official code style, frees up developers most especially those new to the swift language from focusing on style, since the style would be automated with the swift-fmt tool.

+1


(Tyler Phillips) #19

I'm 100% for an Official Swift Style Guide.
I think there is a broad gap between consistency and readability in a lot of projects.
Do I think it would be successful? I'm not 100% certain.
But I do believe it's worth a shot, and ultimately extremely helpful, especially for new comers.


(Lance Parker) #20

I wish I could like this more than once.