[Draft] Expand Document Markup for Mutating/Non-Mutating Cross References


(Erica Sadun) #1

Bringing this over to its own thread. Swift patterns encourage both
functional and procedural implementations for many methods. This
proposal makes it easier to connect those implementations through
Swift doc markup.

Thank you in advance for criticism, suggestions, and feedback. -- E

Expand Document Markup for Mutating/Non-Mutating Cross References

Proposal: SE-00XX
Author(s): Erica Sadun <http://github.com/erica>
Status: TBD
Review manager: TBD
<https://gist.github.com/erica/7a8bfa27d1875401022f50bf4f202027#introduction>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 <applewebdata://4C55665E-EF64-41EE-B112-561AAE5CB6B3>thread.

<https://gist.github.com/erica/7a8bfa27d1875401022f50bf4f202027#motivation>Motivation

The original design for @warn_unused_result provides optional arguments for both message and mutable_variantparameters 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 <http://i.imgur.com/TTF4Y8C.jpg> 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 <https://github.com/apple/swift-evolution/blob/master/proposals/0047-nonvoid-warn.md>, 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 <http://dabrahams.github.io/swift-naming/SetAlgebra-Math.html> 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 <https://swift.org/documentation/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 <https://github.com/apple/swift/blob/master/CHANGELOG.md>
<https://gist.github.com/erica/7a8bfa27d1875401022f50bf4f202027#design-disadvantages>Design Disadvantages

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

<https://gist.github.com/erica/7a8bfa27d1875401022f50bf4f202027#detail-design>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.

<https://gist.github.com/erica/7a8bfa27d1875401022f50bf4f202027#alternatives-considered>Alternatives Considered

There are no alternatives considered.


(Erica Sadun) #2

Please disregard. This has been subsumed back into SE-0047.

Thanks again to the Swift Core team.

-- E

···

On Mar 30, 2016, at 10:51 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Bringing this over to its own thread. Swift patterns encourage both
functional and procedural implementations for many methods. This
proposal makes it easier to connect those implementations through
Swift doc markup.

Thank you in advance for criticism, suggestions, and feedback. -- E

Expand Document Markup for Mutating/Non-Mutating Cross References

Proposal: SE-00XX
Author(s): Erica Sadun <http://github.com/erica>
Status: TBD
Review manager: TBD

blah blah