SE-0199: Adding toggle method to Bool

Some feedback in support of the proposal that was sent to me off-list. Posting here with their permission. Replying to @zzt4 since it provides a use case:

I often reach for toggle when toggling something stored in a data structure to avoid the redundant subscript and better handle optionals.

Given a simple model type for a to-do list task:

struct Task {
   var id: Int
   var body: String
   var isCompleted: Bool
}

and a dictionary of tasks by ID:

var tasksById: [Int:Task]

If you want the optional-chaining no-op on nil behavior:

// without `toggle`
let handler1: (Int) -> Void = { id in
   if let value = self.tasksById[id]?.isCompleted {
       self.tasksById[id]?.isCompleted = !value
   }
}

Combining toggle with optional chaining is a big improvement:

// with `toggle`
let handler2: (Int) -> Void = { id in
   self.tasksById[id]?.isCompleted.toggle()
}

If you want trapping behavior on nil, it’s cleaner:

// trapping alternative without `toggle`
let handler3: (Int) -> Void = { id in
   self.tasksById[id]!.isCompleted = !self.tasksById[id]!.isCompleted
}

But still improved by toggle:

// trapping alternative with `toggle`
let handler4: (Int) -> Void = { id in
    self.tasksById[id]!.isCompleted.toggle()
}
14 Likes