Deep dive into Swift Boolean type

This is the first post in Swift series. Bool is a pretty straight forward and simple data type. Let’s look how it has been implemented.

Bool is a value type. Hence it should be defined using a struct. Indeed it is.

@_fixed_layout
public struct Bool {
  @usableFromInline
  internal var _value: Builtin.Int1
  // ...
  // ...
}

Here we can see the struct has a member named _value which is of type Builtin.Int1 which is an abstraction on Int which uses a single bit but aligned by 8 bits.

Let’s look how the constructors are implemented. By now you might have guessed it right. We might store 0 for falsy and 1 for truthy in _value.

@_transparent
  public init() {
    let zero: Int8 = 0
    self._value = Builtin.trunc_Int8_Int1(zero._value)
  }

The code is very much readable and we get an idea what is going on here. When we declare a Bool variable , by default it will be falsy.

Then we have another constructor that takes in an Int1 value, but this is not public and is for internal use only

@usableFromInline @_transparent
internal init(_ v: Builtin.Int1) { self._value = v }

Then another constructor that takes in a Bool type and assigns from it.

 @inlinable
  public init(_ value: Bool) {
    self = value
  }

Then we have two static random methods out of which one takes a RandomNumberGenerator other one uses the default SystemRandomNumberGenerator

 @inlinable
  public static func random<T: RandomNumberGenerator>(
    using generator: inout T
  ) -> Bool {
    return (generator.next() >> 17) & 1 == 0
  }

  @inlinable
  public static func random() -> Bool {
    var g = SystemRandomNumberGenerator()
    return Bool.random(using: &g)
  }

These methods allow us to write boolean expressions such as:

let flippedHeads = Bool.random() or let flippedHeads = Bool.random(using: &myGenerator)

Then we have several extensions on Bool which make it conform to protocols ExpressibleByBooleanLiteral, CustomStringConvertible, Equatable, Hashable, LosslessStringConvertible

Then we have the operators acting upon a Bool.

It is this piece of code that helps us to write code like let flippedValue = !value. You can see it is implemented as an xor operation between truthy and current value

@_transparent
  public static prefix func ! (a: Bool) -> Bool {
    return Bool(Builtin.xor_Int1(a._value, true._value))
  }

Then we have the && operation that we use on Bool.

 @_transparent
  @inline(__always)
  public static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
      -> Bool {
    return lhs ? try rhs() : false
  }

Here the implementation uses short circuit evaluation where if the first one evaluates to false, then rhs is not at all evaluated. And the rhs uses a @autoclosure. It helps us to write an expression and swift will generate the closure for us automatically. Hence we are able to write something like let a = flippedValue && someSlowMethod()

Here, if the flippedValue is false then the someSlowMethod won’t be even invoked. And we are able to write such an expression because of the @autoclosure signature.

Same goes with the logical or operator

@_transparent
@inline(__always)
public static func || (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
    -> Bool {
  return lhs ? true : try rhs()
}

Another thing to note is the rethrows keyword that is being used. It tells the compiler that the || operation will throw only if the rhs is an expression that throws. Hence we wont need to wrap every || in try catch unless it has a throwing method in the evaluation.

And then comes my personal favourite toggle method which was introduced in Swift 4.2.

@inlinable
public mutating func toggle() {
  self = !self
}

This was quite controversial when introduced in the Swift evolution. Eventhough it is a simple method, the beauty comes in the caller side. Most often in my apps, I would have to write code to show and hide some element. It used to be

@objc func toggleSidebar() {
  splitViewItems.first?.animator().isCollapsed = !splitViewItems.first?.animator().isCollapsed
}

is now replaced by

@objc func toggleSidebar() {
  splitViewItems.first?.animator().isCollapsed.toggle()
}

This is much more clean and concise. It’s a joy to use toggle

This is all of the code of Bool type as of the day I am writing this post. We have here lot of swift constructs and tricks like auto closure, rethrows, short circuit evaluation etc. Moreover now you know how the Bool is implemented in your favourite language!

Cheers!