If you can't come up with a good name for it, then it's a mess. The names are the API talking back to you, so listen to them
- Guy Steele
Software development requires a huge amount of memorization. Consistent naming conventions reduce the Conceptual Weight of an API making everyones day to day a lot easier.
https://swift.org/documentation/api-design-guidelines/#promote-clear-usage
Clarity at the point of use is your most important goal. Entities such as methods and properties are declared only once but used repeatedly. Design APIs to make those uses clear and concise. When evaluating a design, reading a declaration is seldom sufficient; always examine a use case to make sure it looks clear in context.
Clarity is more important than brevity. Although Swift code can be compact, it is anon-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system and features that naturally reduce boilerplate.
Include all the words needed to avoid ambiguity for a person reading code where the name is used.
Omit needless words. Every word in a name should convey salient information at the use site.
Name variables, parameters, and associated types according to their roles, rather than their type constraints.
Include all the words needed to avoid ambiguity for a person reading code where the name is used.
employees.remove(at: x)
// :(
employees.remove(x)
// unclear:
// are we removing x or are we removing at?
// :)
extension List {
public mutating func remove(at position: Index) -> Element
}
Omit needless words. Every word in a name should convey salient information at the use site.
//Bad :(
public mutating func removeElement(member: Element) -> Element?
allViews.removeElement(cancelButton)
//Good :)
public mutating func remove(member: Element) -> Element?
allViews.remove(cancelButton) // clearer
Name variables, parameters, and associated types according to their roles, rather than their type constraints.
// :(
protocol ViewController {
//Everyone knows what a view is. Describe what kind of view.
associatedtype ViewType : View
}
// :)
protocol ViewController {
associatedtype CircularSliderView : View
}
Prefer method and function names that make use sites form grammatical English phrases.
// :(
x.insert(y, position: z)
x.subViews(color: y)
x.nounCapitalize()
// :)
x.insert(y, at: z) // x, insert y at z
x.subViews(havingColor: y) // x's subviews having color y
x.capitalizingNouns() // x, capitalizing nouns
Name functions and methods according to their side-effects
Use the “ed/ing” rule to name the non mutating counterpart of a mutating method
x.sort()
x.sorted()
x.append(y)
x.appending(y)
x.stripNewlines()
x.strippingNewlines()
// In each case
// The example alters the original.
// The original doesn't change. Instead it returns an altered copy.
These conventions allow you to know exactly what a method is doing without reading any source code or documentation and minimal memorization.
Don't surprise your readers. Consistent and obvious patterns throughout the code base make development easier for both beginner and expert developers.
Only overload methods when they have the same basic meaning.
extension Shape {
/// Returns `true` iff `other` is within the area of `self`.
func contains(other: Point) -> Bool { ... }
/// Returns `true` iff `other` is entirely within the area of `self`.
func contains(other: Shape) -> Bool { ... }
/// Returns `true` iff `other` is within the area of `self`.
func contains(other: LineSegment) -> Bool { ... }
}
extension Database {
/// Rebuilds the database's search index
func index() { ... }
/// Returns the `n`th row in the given table.
func index(n: Int, inTable: TableID) -> TableRow { ... }
}
extension Box {
/// Returns the `Int` stored in `self`, if any, and
/// `nil` otherwise.
func value() -> Int? { ... }
/// Returns the `String` stored in `self`, if any, and
/// `nil` otherwise.
func value() -> String? { ... }
}
What not to do...