Naming Conventions

Why are Naming Conventions Important?

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. 

Learning Lesons from the

Swift API Design Guidelines

https://swift.org/documentation/api-design-guidelines/#promote-clear-usage

Fundamentals

  • 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.

Naming: Nouns and Verbs

  • Uses of Boolean methods and properties should read as assertions about the receiver when the use is nonmutating.
    Example: x.isEmpty, line1.intersects(line2)
  • Protocols that describe what something is should read as nouns. 
    Example: Collection
  • Protocols (interfaces) that describe a capability should be named using the suffixes able, ible, or ing
    Example: Equatable, ProgressReporting
  • The names of other types, properties, variables, and constants should read as nouns

Naming: Word Choice

  • 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.

  • Prefer method and function names that make use sites form grammatical English phrases.
  • Name functions and methods according to their side-effects

Naming: Word Choice

  • 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
}

Naming: Word Choice

  • 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

Naming: Word Choice

  • 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 
}

Naming: Word Choice

  • 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

Naming: Word Choice

  • 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. 

Naming

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. 

Naming: Thoughts on Terminology

  • Avoid abbreviations: Abbreviations, especially non-standard ones, are effectively terms-of-art, because understanding depends on correctly translating them into their non-abbreviated forms.
     
  • Embrace precedent: Don’t optimize terms for the total beginner at the expense of conformance to existing culture.

Naming: Overloading

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 { ... }
}

Naming: Overloading

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...

Made with Slides.com