avismara avismara - 6 months ago 22
Swift Question

Why is Swift's fatalError's argument an @autoclosure?

I was poking around Swift to find out that

fatalError
has this signature:

@noreturn public func fatalError(@autoclosure message: () -> String = default, file: StaticString = #file, line: UInt = #line)


Any specific reason as to why this function is defined this way? What is wrong with :

@noreturn public func fatalError(message:String = default, file: StaticString = #file, line: UInt = #line) {
//Termination code
}


Note that I understand how
@autoclosure
works, and this question is not about its usage; but about the use-cases where such a pattern could be used.

Answer

It is used to optionally evaluate statement to reduce overhead.

For this code

fatalError("\(someExpansiveComputation())")

If the function is defined with normal parameter passing, then someExpansiveComputation() will always be called, even in production build.

However with @autoclosure, the implementation of fatalError can choose not call the closure, to avoid the overhead of calling someExpansiveComputation()

a possible implementation can be

@noreturn public func fatalError(message:String = default, file: StaticString = #file, line: UInt = #line) {
    if debug || errorReportingEnabled {
        log(message()) // only compute the message if necessary 
    }
    abort()
}