ProgrammingiOS Developer

What is autoclosure in Swift? What is @autoclosure used for and what pitfalls are there when using it?

Pass interviews with Hintsage AI assistant

Answer.

Background:

@autoclosure is a special Swift modifier that allows for the automatic creation of a closure from an expression passed as a function argument. It first appeared to simplify syntax and improve readability when writing assert/guard expressions and deferred value computations.

Problem:

Standard closures require explicit syntax ({ ... }). This is often redundant when the logic is simple (for example, in lazy checks). However, using autoclosure can subtly change the execution timing of the code or lose the side-effect value of the expression, unnoticed by the developer. Moreover, autoclosure does not take parameters.

Solution:

@autoclosure allows for concise writing:

Code example:

func logIfTrue(_ predicate: @autoclosure () -> Bool) { if predicate() { print("Condition met") } } // Without autoclosure: logIfTrue({ 2 > 1 }) // With autoclosure: logIfTrue(2 > 1)

Key features:

  • @autoclosure allows deferring the evaluation of the expression until the function is called
  • @autoclosure can be combined with @escaping for asynchronous scenarios
  • Improves the readability of interfaces by hiding closure syntax from the API user

Trick questions.

Can autoclosure take parameters?

No. Autoclosure is always context-free: it takes 0 parameters and simply "wraps" the expression.

What is the difference between types () -> T and @autoclosure () -> T?

A regular closure requires explicit syntax — autoclosure allows passing an expression without surrounding it with curly braces, which significantly impacts function interfaces.

What happens if autoclosure has a side-effect?

The autoclosure is computed only when called — if the expression performs a side effect, it will occur strictly at the time of the call, not when passing the parameter to the function.

var x = 5 func change(_ value: @autoclosure () -> Int) { print(value()) } change(x += 1) // x will only increase HERE

Common mistakes and anti-patterns

  • Misunderstanding that the expression does not execute immediately (lazy behavior)
  • Using autoclosure with side-effect expressions, where immediate execution is expected
  • Passing autoclosure into an escaping context without explicit @escaping indication

Real-life example

Negative case

In implementing error analytics, messages were written using a function that employed autoclosure for reporting. However, the message expression had a side effect (it sent a network request), so the actual execution happened out of the expected order for the developer. Consequently, the statistics were collected incorrectly.

Pros:

  • Short and expressive syntax

Cons:

  • Unclear side-effect execution timing
  • Troubles during debugging

Positive case

Using autoclosure in assert methods, where it is either required to compute an expression only when necessary, or to simplify the syntax for the API end-user. The code becomes shorter, with no side effect.

Pros:

  • Improved readability and ease of use
  • Simple lazy evaluation

Cons:

  • Can lead to excessive magic if developers are not familiar with autoclosure behavior