Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ##Introduction because I have OCD
- Swift prizes clarity. Its parameter labeling system emphasizes self-documentation
- and guides code production. In nearly every case, labels follow
- three simple rules:
- * Skip argument labels for a method or function's first parameter
- * Use argument labels for a method or function's subsequent parameters
- * Require argument labels for initializers
- These base rules enhance Swift legibility. Unlike other languages whose positional argument
- names have meaning only within the implementation context, Swift's labels convey use and
- meaning at the calling site. This creates better communication, enhances maintainability,
- and adheres to the principle that code is written rarely and read and reviewed often.
- At times, special circumstances may apply to your code as explored in the following rules:
- ------
- ###Dave:
- If and only if the first argument could complete a sentence*
- beginning in the base name and describing the primary semantics of
- the call, it gets no argument label:
- a.contains(b) // b completes the phrase "a contains b"
- a.mergeWith(b) // b completes the phrase "merge with b"
- a.dismiss(animated: b) // "a, dismiss b" is a sentence but
- // doesn't describe the semantics at all,
- // thus we add a label for b.
- a.moveTo(x: 300, y: 400) // "a, move to 300" is a sentence
- // but doesn't describe the primary
- // semantics, which are to move in both
- // x and y. Thus, x gets a label.
- a.readFrom(u, ofType: b) // "a, read from u" describes
- // the primary semantics, so u gets no
- // label. b is an
- // option that tunes the primary
- // semantics
- [Note that this covers all the direct object cases and, I believe,
- all the default argument cases too, so maybe that exception can be
- dropped. We still need the exceptions for full-width type
- conversions and indistinguishable peers]
- ------
- * *Skip first argument labels* when the first argument completes a sentence established in the base name. If the argument describes a call's primary semantics, it does not require a label:
- ```swift
- a.contains(b) // b completes the phrase "a contains b"
- a.mergeWith(b) // b completes the phrase "merge with b"
- a.readFrom(u, ofType: b) // "a, read from u" describes
- // primary semantics so u gets no
- // label.
- // b is an option that tunes the
- // primary semantics
- ```
- **Changes** Rule is now a directive. Dismiss and moveTo are moved to their own rules. I only minorly tweaked the comments.
- ------
- ###Dave:
- Note: when there is a noun in the base name describing the role of the
- first argument, we skip it in considering this criterion:
- a.addObserver(b) // "a, add b" completes a sentence describing
- // the semantics. "Observer" is omitted in
- // making this determination.
- ----
- * *Skip the first argument label* when a noun in the base name describes the first argument's role.
- ```swift
- a.addObserver(b) // "add b" completes a meaningful sentence that
- // defines the intended semantics. The first
- // argument is the "Observer".
- ```
- **Changes** Rephrasing, rule directive, rewrote comments
- -----
- ###Dave:
- 3. (this one is separable) When the first argument is the *name* or
- *identifier* of the subject in the base name, do not label it or
- describe it in the base name.
- a.transitionToScene(.GreatHall) // yes
- a.transitionToSceneWithIdentifier(.GreatHall) // no
- let p = someFont.glyph("propellor") // yes
- let p = someFont.glyphWithName("propellor") // no
- let p = someFont.glyph(name: "propellor") // no
- ----
- * *Move the first argument label* to the base name when it describes a name or identifier that acts as the subject of the base action.
- ```swift
- a.transitionToScene(.GreatHall) // yes
- a.transitionToSceneWithIdentifier(.GreatHall) // no
- let p = someFont.glyph("propellor") // yes
- let p = someFont.glyphWithName("propellor") // no
- let p = someFont.glyph(name: "propellor") // no
- ```
- **Changes** Rule directive, grouped below with similar rule
- ----
- ###Dave:
- 2. Words that describe attributes of an *already-existing* instance
- should go in the base name rather than in a label:
- a.tracksHavingMediaType("Wax Cylinder") // yes
- a.removeFirstTrackHavingMediaType("BetaMax") // yes
- a.tracks(mediaType: "Wax Cylinder") // no
- a.removeFirstTrack(havingMediaType: "BetaMax") // no
- [yes, we could use "With" instead of "Having", but it's more
- ambiguous]
- Words that describe attributes of an instance *to be created* should
- go in argument labels, rather than the base name (for parity with
- initializers):
- AudioTrack(mediaType: "BetaMax") // initializer
- trackFactory.newTrack(mediaType: "Wax Cylinder") // yes
- trackFactory.newTrackWithMediaType("Wax Cylinder") // no
- ----
- * *Move the first argument label* to the base name when it describes argument attributes of existing instances.
- ```swift
- a.tracksOfMediaType("Wax Cylinder") // yes
- a.removeFirstTrackOfMediaType("BetaMax") // yes
- a.tracks(mediaType: "Wax Cylinder") // no
- a.removeFirstTrack(havingMediaType: "BetaMax") // no
- ```
- **Changes** Rule directive, grouped with previous rule, split out initializer-like rules for later, changed first "Having" to "Of" because that's the way I roll.
- ----
- * *Use first label arguments* when the first parameter is semantically distinct from the base name and does not complete a meaningful "sentence"
- ```swift
- a.dismiss(animated: b) // "a, dismiss b" is a sentence but
- // doesn't describe the semantics at all,
- // thus we add a label for b.
- ```
- ----
- **Changes** Broke this one out into its own rule because it's about when not to merge into base name but still use a label. By the way, I loathe "we" voice.
- ----
- * *Use all argument labels* when the relationship between arguments is semantically stronger than
- the relationship between the first argument and the base name.
- ```swift
- moveTo(x: a, y: b)
- login(userName: a, password: b)
- constructColor(red: r, green: g, blue: b, alpha: a)
- ```
- ----
- **Changes** Completely new rule
- ----
- * *Omit labels* for argument peers that cannot be usefully distinguished.
- ```swift
- min(number1, number2)
- zip(sequence1, sequence2)
- ```
- ----
- **Changes** Stolen from doc, moved here because it fits, and rephrased a teeeeeny bit to make it more a directive
- What follows next is a group of initializer-ish rules grouped together.
- ----
- * *Use explicit argument labels* to describe attributes of an instance that's *being created*.
- Your calls should resemble initializers.
- ```
- AudioTrack(mediaType: "BetaMax") // initializer
- trackFactory.newTrack(mediaType: "Wax Cylinder") // yes
- trackFactory.newTrackOfMediaType("Wax Cylinder") // no
- ```
- * *Use first argument labels* that would have normally appeared in the base name when building
- groups of related calls whose implementations are distinguished specifically by their parameters.
- Your calls should resemble initializers.
- ```swift
- login(userName: a, password: b) // not loginWithUserName(a, password: b)
- login(credential: a) // not loginWithCredential(a)
- ```
- ----
- **Changes** New rule
- ----
- * *Skip first argument labels* for initializers when using full width type conversions, that is
- when initializing from instances of another type.
- ```swift
- extension String {
- // Convert `x` into its textual representation
- // in the given radix
- init(_ x: BigInt, radix: Int = 10)
- }
- text = "The value is: "
- text += String(veryLargeNumber)
- text += " and in hexadecimal, it's"
- text += String(veryLargeNumber, radix: 16)
- ```
- * *Use first argument labels* when narrowing initial values to make it conform
- to restrictions within the new type. The label should describe how the instance
- will be modified:
- ```swift
- extension UInt32 {
- init(_ value: Int16) // Widening, so no label
- init(truncating bits: UInt64)
- init(saturating value: UInt64)
- }
- ```
- ----
- **Changes** Both of these are stolen from docs, but rephrased to be more readable
- ----
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement