Pre-Pitch: Explicit protocol fulfilment with the 'conformance' keyword

Maybe the pitch would be better if I made explicit an underlying idea regarding documentation.

The conformance keyword is pitched as optional. One does not have to use it. One has benefits using it, because it reveals some present or future mismatches between the programmer intent, and what the compiler sees. By "present mismatch", I mean typos and near-misses. By "future mismatch", I mean code that must change because a dependency has changed the definition of a protocol.

It is a tool that I initially intended for three groups of people:

  1. Programmers who are aware of the benefits of the keyword, for their own code base.
  2. Documentation writers, who would start recommending the use of the conformance keyword in the documentation of some protocols, when relevant.
  3. Clueless documentation readers, who use the conformance keyword because that's what the sample code says in the documentation. And that's as good for them as it is good for the programmers who are aware of what they are doing.

The benefits of conformance for the first group have been explained above.

The benefits of conformance for the documentation writers is two-fold:

  1. Some documentation can be simplified. The example below comes from GRDB (original), and was considered necessary due to the high risk of miss due to type-inference:

    Note: make sure the databaseSelection property is explicitly declared as [any SQLSelectable]. If it is not, the Swift compiler may silently miss the protocol requirement, resulting in sticky SELECT * requests.

    This paragraph aims at avoiding this kind of bug:

    struct Player: TableRecord {
        // MISS: '[Column]' is not '[any SQLSelectable]'
        static let databaseSelection = [Column("id"), Column("name")]
    }
    

    The conformance keyword would enter the sample code provided in the documentation. When the reader follows the advice, it is for their own benefit.

  2. Migration guides can be simplified. Again, consider this GRDB example (original):

    It is no longer possible to override persistence methods such as insert or update. Customizing the persistence methods is now possible with callbacks such as willSave, willInsert, or didDelete [...].

    [When upgrading] you have to remove the methods below from your own code base: [followed by a list of now-retired customization points].

    Of course the GRDB author is sorry to introduce breaking changes. That's why there is a migration guide. This guide would have been much easier to write if users could have used conformance before. The compiler would have shown the obsolete requirements without any ambiguity, guiding the user in the upgrade. Without it, an exhaustive list of functions that need to be updated is difficult to build (even if one groups conformances in dedicated extensions).

1 Like