Pro Tip: Boolean chaining

You might occasionally reach a state where a status is defined by a sequence of boolean values. This is common occurrence when dealing with state machines, here’s an abstracted example:


var isConnected : Bool = true
var hasData : Bool = true
var isDataStale: Bool = false

var isDataReadyForPresentation : Bool {
  return isConnected && hasData && !isDataStale
}

Depending on the complexity of your state machine, the definition of the variable ‘isDataReadyForPresentation‘ would be sufficient, but if calculating this value depends on a sequence of  a large number of values, you quickly will loose readability on a long line of boolean conditions.

Some developers might try to mitigate with a solution composed as a sequence of if statements:


var isDataReadyForPresentation : Bool {
  if isConnected {
    if hasData {
      return !isDataStale
    }
  }
  return false
}

This is a naive approach that will very quickly get messy.

The old Obj-C ways had an elegant solution called boolean inclusion/exclusion, or as I like to call it, boolean chaining, that allows you to be a neat developer by compacting all boolean checks into different lines.

Unfortunately, this doesn’t come as part of the Swift package…But fortunately, there is an easy way to bring it in! All you need to do is add a new .swift file into our project with the following global functions:


fun &=(inout left: Bool, right: Bool) {
  left = left && right
}

func |=(inout left: Bool, right: Bool) {
  left = left || right
}

This will allow us to chain booleans on different lines using inclusion ‘&&‘ and exclusion ‘||‘ operations, in the same way you would have previously done in Obj-C, for example:


let yes = true
let no = false

var variable = true

variable &= yes   // true
variable &= no    // false
variable &= yes   //false

variable |= no    //false
variable |= yes   //true
variable |= no    //true

This allows us to rewrite our state machine using a much cleaner and easier to follow solution:


var isConnected : Bool = true
var hasData : Bool = true
var isDataStale: Bool = false

var isDataReadyForPresentation : Bool {
  var value = isConnected
  value &= hasData
  value &= !isDataStale
  return value
}

As always, I’ve provided a small sample project related to this blog post on my GitHub page.

Happy Coding!

Author: Danny Bravo

Director @ EPIC