Categories
Swift

Add vs. Adding

A few weeks ago, I was watching an online video which presented a way to generate an object following the Builder Pattern.
I hear something very interesting which I believe is a convention within the Swift world on how to name some of your methods within your API objects.

Add versus Adding or more generic, [Action] versus [Action]-ing

Imagine you have an object, which acts as a Collection and stores items, but you want to have the possibility to insert item(s) into this object. I was usually using the function name add, as simple as that. But swift has a convention which I didn’t know:

  • add for the mutable version
  • adding for the fluent version (returns a copy of the initial object)

Example

Let’s get a simple example. My object will represent an Array of items which should have always at least one element, and we can only add more later on.

 struct ArrayWithAtLeast1Item<T> {
     
     private let head: T
     private let tail: [T]
     
     init(_ head: T, _ tail: [T]) {
         self.head = head
         self.tail = tail
     }
     
     init(_ head: T, _ tail: T...) {
         self.head = head
         self.tail = tail
     }
     
     var all: [T] {
         [head] + tail
     }
     
     mutating func add(_ element: T) {
         self = adding(element)
     }
     
     func adding(_ element: T) -> ArrayWithAtLeast1Item<T> {
         return ArrayWithAtLeast1Item(head, tail + [element])
     }
 } 

What you can see here is a simple struct object, which keeps reference to a list of items. The API provides two methods to insert items into it.

  • The function add, is mutable, therefore will modify the existing object, and insert the new item at the end of the list.
  • The function adding, is immutable, therefore will return a new copy of the object, with the item added at the end of the list.

Usage

let immutableArray = ArrayWithAtLeast1Item(1)
                              .adding(2)
                              .adding(3)
         
var mutableArray = ArrayWithAtLeast1Item(1)
mutableArray.add(2)
mutableArray.add(3) 

Notice the usage of var / let for using our struct object. What is great is also that the compiler will let us know in case we are using the wrong available function.

What is nice when you write an object API which can provide such a functionality, is to provide both variations. Therefore, the client of your API will be free to choose the version he/she prefers.

If you check carefully the Apple documentation you will find often this kind of convention, like in the Date object:

 struct Date {
 
    mutating func addTimeInterval(_ timeInterval: TimeInterval)
     
    func addingTimeInterval(_ timeInterval: TimeInterval) -> Date
 } 

Thank you for reading until here…  👊 Enjoy(-ing) the week end…  🍺