Alexito's World

A world of coding 💻, by Alejandro Martinez

Hole Driven Development in Swift

While programming with a static type system there are times when you write the definition of a function but you still don’t have any idea on how to implement it.

func importantFunction(input: String) -> GreatOutputType {
  // ?
}

But if you're still writing the usage code you don't really care if this function is not completed, yet. The issue is that without an implementation the compiler will complain that the function doesn’t return the proper value.

In simple cases you can avoid that by just returning some simple literal.

func simpleReturnType(input: String) -> Int {
  return 0
}

But in others it may not be that easy to return a proper value from the return type, and we don't really care now, we're too focused on writing the rest of the program.

Some languages have the concept holes, placeholder values that adopt the form of any type and that you can use to satisfy the type system while you finish coding. Swift doesn’t have this direct feature but fatalError() is a good enough replacement for it.

func importantFunction(input: String) -> GreatOutputType {
    fatalError()
}

fatalError() is defined to return a Never. Never is a bottom type that can't be constructed, there is no possible value of that type. This means the function can’t return and makes the compiler stop complaining about the missing return value. With a the compiler and type system happy you can keep coding the rest of the program until you come up with an implementation for that function.

This is really useful to help you design your code around types and functions, even if the functions are not fully implemented yet.

If you liked this article please consider supporting me