Skip to content

Instantly share code, notes, and snippets.

@erica
Last active March 30, 2016 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/7a8bfa27d1875401022f50bf4f202027 to your computer and use it in GitHub Desktop.
Save erica/7a8bfa27d1875401022f50bf4f202027 to your computer and use it in GitHub Desktop.

Expand Document Markup for Mutating/Non-Mutating Cross References

  • Proposal: SE-00XX
  • Author(s): Erica Sadun
  • Status: TBD
  • Review manager: TBD

Introduction

Mutating and non-mutating pairs form a common Swift pattern. This proposal extends document markup to add description field labels that cross reference functional and procedural variations.

This proposal was discussed on-list in the [Draft] Expand Document Markup for Mutating/Non-Mutating Cross References thread.

Motivation

The original design for @warn_unused_result provides optional arguments for both message and mutable_variant parameters that customize warnings when a method or function is called without consuming a result.

    @warn_unused_result(mutable_variant="sortInPlace")
    public func sort() -> [Self.Generator.Element]

In Swift 2.2, cross references appear in a function's QuickHelp declaration field. This screenshot shows an example. Although ugly, doc-based cross referencing provides a valuable tool for developers seeking correspondence between two related functions. While, in compiler terms, it makes no sense to provide an equivalent variant and message option when attempting to consume the Void return type of mutating members. Most Void functions are not paired with a non-mutating member. By adding a highlighted field to documentation, both the mutating and non-mutating variations can cross-reference each other.

SE-0047, which defaults non-Void functions to warn on unused results, initially proposed to extend Swift markup to introduce two field labels, specifically mutatingVariant and nonmutatingVariant. Field labels establish bidirection alternatives and incorporate the freeform messages originally designed into @warn_unused_result.

Swift's current markup includes: attention, important, note, remark,  and SeeAlso. Each of these could convey the relationship between mutating and non-mutating pairs like sort and sorted. To counter that argument, consider the following points:

  • Using named keywords instantly identifies why the documentation is calling these items out and promoting their names, rather than promoting some  general relationship like SeeAlso. QuickHelp highlighted keywords support the expert and guide the beginner, adding value in a way SeeAlso cannot.

  • Mutating and non-mutating pairs reflect a specific Swift pattern that differentiates functional implementations from their related procedural cousins. Some efforts, such as Dave Abraham's Set Algebra extensions are entirely built on creating and naming mutating/non-mutating pairs.

  • The current compiler-only approach is strictly one-way. These keywords support the developer in both directions and help avoid undesirable patterns like let self = nonMutatingCall.

  • Mutating and non-mutating pairs are are specifically called out in the API naming guide discussion on side effects.

  • Those without side-effects should read as noun phrases, e.g. x.distance(to: y), i.successor().
  • Those with side-effects should read as imperative verb phrases, e.g., print(x), x.sort(), x.append(y).
  • Use the “ed/ing” rule to name the nonmutating counterpart of a mutating method, e.g. x.sort()/x.sorted() and x.append(y)/x.appending(y).

Often, a mutating method will have a nonmutating variant returning the same, or a similar, type as the receiver. Prefer to name the nonmutating variant using the verb’s past participle (usually appending “ed”): When adding “ed” is not grammatical because the verb has a direct object, name the nonmutating variant using the verb’s present participle, by appending “ing.”

Source: The Swift API Design Guidelines

  • Swift's recent recommended/recommendedOver expansion lends weight that doc patterns that specifically serve developer needs can be added in modern Swift.

Three new document comment fields, namely - keyword:, - recommended: and - recommendedover:, allow Swift users to cooperate with code completion engine to deliver more effective code completion results. The - keyword: field specifies concepts that are not fully manifested in declaration names. - recommended: indicates other declarations are preferred to the one decorated; to the contrary, - recommendedover: indicates the decorated declaration is preferred to those declarations whose names are specified.

Source: The Swift master change log

Design Disadvantages

Being a documentation expansion, this approach excludes compile-time verification of method/function signatures.

Detail Design

This proposal introduces two new document comment fields. The - mutatingVariant: and - nonmutatingVariant: fields indicate paired members with and without side effects, offering instant reference for developers considering moving to or from in-place implementation.

Alternatives Considered

There are no alternatives considered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment