# Prefix Expressions

> In Swift, there are four kinds of expressions: prefix expressions, infix expressions, primary expressions, and postfix expressions. Evaluating an expression returns a value, causes a side effect, or both.

- Skill: `tools-only/prefix-expressions` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/prefix-expressions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/prefix-expressions/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/prefix-expressions

---

# Expressions

Access, modify, and assign values.

In Swift, there are four kinds of expressions:
prefix expressions, infix expressions, primary expressions, and postfix expressions.
Evaluating an expression returns a value,
causes a side effect, or both.

Prefix and infix expressions let you
apply operators to smaller expressions.
Primary expressions are conceptually the simplest kind of expression,
and they provide a way to access values.
Postfix expressions,
like prefix and infix expressions,
let you build up more complex expressions
using postfixes such as function calls and member access.
Each kind of expression is described in detail
in the sections below.

> Grammar of an expression:
>
> *expression* → *try-operator*_?_ *await-operator*_?_ *prefix-expression* *infix-expressions*_?_

## Prefix Expressions

*Prefix expressions* combine
an optional prefix operator with an expression.
Prefix operators take one argument,
the expression that follows them.

For information about the behavior of these operators,
see <doc:BasicOperators> and <doc:AdvancedOperators>.

For information about the operators provided by the Swift standard library,
see [Operator Declarations](https://developer.apple.com/documentation/swift/operator_declarations).

> Grammar of a prefix expression:
>
> *prefix-expression* → *prefix-operator*_?_ *postfix-expression* \
> *prefix-expression* → *in-out-expression*

### In-Out Expression

An *in-out expression* marks a variable
that's being passed
as an in-out argument to a function call expression.

```swift
&<#expression#>
```

For more information about in-out parameters and to see an example,
see <doc:Functions#In-Out-Parameters>.

In-out expressions are also used
when providing a non-pointer argument
in a context where a pointer is needed,
as described in <doc:Expressions#Implicit-Conversion-to-a-Pointer-Type>.

> Grammar of an in-out expression:
>
> *in-out-expression* → **`&`** *primary-expression*

### Try Operator

A *try expression* consists of the `try` operator
followed by an expression that can throw an error.
It has the following form:

```swift
try <#expression#>
```

The value of a `try` expression is the value of the *expression*.

An *optional-try expression* consists of the `try?` operator
followed by an expression that can throw an error.
It has the following form:

```swift
try? <#expression#>
```

If the *expression* doesn't throw an error,
the value of the optional-try expression
is an optional containing the value of the *expression*.
Otherwise, the value of the optional-try expression is `nil`.

A *forced-try expression* consists of the `try!` operator
followed by an expression that can throw an error.
It has the following form:

```swift
try! <#expression#>
```

The value of a forced-try expression is the value of the *expression*.
If the *expression* throws an error,
a runtime error is produced.

When the expression on the left-hand side of an infix operator
is marked with `try`, `try?`, or `try!`,
that operator applies to the whole infix expression.
That said, you can use parentheses to be explicit about the scope of the operator's application.

```swift
// Writing 'try' applies to both function calls.
sum = try someThrowingFunction() + anotherThrowingFunction()

// Writing 'try' applies to both function calls.
sum = try (someThrowingFunction() + anotherThrowingFunction())

// Error: Writing 'try' applies only to the first function call.
sum = (try someThrowingFunction()) + anotherThrowingFunction()
```

<!--
  - test: `placement-of-try`

  ```swifttest
  >> func someThrowingFunction() throws -> Int { return 10 }
  >> func anotherThrowingFunction() throws -> Int { return 5 }
  >> var sum = 0
  // Writing 'try' applies to both function calls.
  -> sum = try someThrowingFunction() + anotherThrowingFunction()

  // Writing 'try' applies to both function calls.
  -> sum = try (someThrowingFunction() + anotherThrowingFunction())

  // Error: Writing 'try' applies only to the first function call.
  -> sum = (try someThrowingFunction()) + anotherThrowingFunction()
  !$ error: call can throw but is not marked with 'try'
  !! sum = (try someThrowingFunction()) + anotherThrowingFunction()
  !!                                      ^~~~~~~~~~~~~~~~~~~~~~~~~
  !$ note: did you mean to use 'try'?
  !! sum = (try someThrowingFunction()) + anotherThrowingFunction()
  !!                                      ^
  !!                                      try
  !$ note: did you mean to handle error as optional value?
  !! sum = (try someThrowingFunction()) + anotherThrowingFunction()
  !!                                      ^
  !!                                      try?
  !$ note: did you mean to disable error propagation?
  !! sum = (try someThrowingFunction()) + anotherThrowingFunction()
  !!                                      ^
  !!                                      try!
  ```
-->

A `try` expression can't appear on the right-hand side of an infix operator,
unless the infix operator is the assignment operator
or the `try` expression is enclosed in parentheses.

<!--
  - test: `try-on-right`

  ```swifttest
  >> func someThrowingFunction() throws -> Int { return 10 }
  >> var sum = 0
  -> sum = 7 + try someThrowingFunction() // Error
  !$ error: 'try' cannot appear to the right of a non-assignment operator
  !! sum = 7 + try someThrowingFunction() // Error
  !!           ^
  -> sum = 7 + (try someThrowingFunction()) // OK
  ```
-->

If an expression includes both the `try` and `await` operator,
the `try` operator must appear first.

<!--
  The "try await" ordering is also part of the grammar for 'expression',
  but it's important enough to be worth re-stating in prose.
-->

For more information and to see examples of how to use `try`, `try?`, and `try!`,
see <doc:ErrorHandling>.

> Grammar of a try expression:
>
> *try-operator* → **`try`** | **`try`** **`?`** | **`try`** **`!`**

### Await Operator

An *await expression* consists of the `await` operator
followed by an expression that uses the result of an asynchronous operation.
It has the following form:

```swift
await <#expression#>
```

The value of an `await` expression is the value of the *expression*.

An expression marked with `await` is called a *potential suspension point*.
Execution of an asynchronous function can be suspended
at each expression that's marked with `await`.
In addition,
execution of concurrent code is never suspended at any other point.
This means code between potential suspension points
can safely update state that requires temporarily breaking invariants,
provided that it completes the update
before the next potential suspension point.

An `await` expression can appear only within an asynchronous context,
such as the trailing closure passed to the `async(priority:operation:)` function.
It can't appear in the body of a `defer` statement,
or in an autoclosure of synchronous function type.

When the expression on the left-hand side of an infix operator
is marked with the `await` operator,
that operator applies to the whole infix expression.
That said, you can use parentheses
to be explicit about the scope of the operator's application.

```swift
// Writing 'await' applies to both function calls.
sum = await someAsyncFunction() + anotherAsyncFunction()

// Writing 'await' applies to both function calls.
sum = await (someAsyncFunction() + anotherAsyncFunction())

// Error: Writing 'await' applies only to the first function call.
sum = (await someAsyncFunction()) + anotherAsyncFunction()
```

<!--
  - test: `placement-of-await`

  ```swifttest
  >> func someAsyncFunction() async -> Int { return 10 }
  >> func anotherAsyncFunction() async -> Int { return 5 }
  >> func f() async {
  >> var sum = 0
  // Writing 'await' applies to both function calls.
  -> sum = await someAsyncFunction() + anotherAsyncFunction()

  // Writing 'await' applies to both function calls.
  -> sum = await (someAsyncFunction() + anotherAsyncFunction())

  // Error: Writing 'await' applies only to the first function call.
  -> sum = (await someAsyncFunction()) + anotherAsyncFunction()
  >> _ = sum  // Suppress irrelevant written-but-not-read warning
  >> }
  !$ error: expression is 'async' but is not marked with 'await'
  !! sum = (await someAsyncFunction()) + anotherAsyncFunction()
  !! ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  !! await
  !$ note: call is 'async'
  !! sum = (await someAsyncFunction()) + anotherAsyncFunction()
  !! ^
  ```
-->

An `await` expression can't appear on the right-hand side of an infix operator,
unless the infix operator is the assignment operator
or the `await` expression is enclosed in parentheses.

<!--
  - test: `await-on-right`

  ```swifttest
  >> func f() async {
  >> func someAsyncFunction() async -> Int { return 10 }
  >> var sum = 0
  >> sum = 7 + await someAsyncFunction()    // Error
  !$ error: 'await' cannot appear to the right of a non-assignment operator
  !! sum = 7 + await someAsyncFunction()    // Error
  !! ^
  >> sum = 7 + (await someAsyncFunction())  // OK
  >> _ = sum  // Suppress irrelevant written-but-not-read warning
  >> }
  ```
-->

If an expression includes both the `await` and `try` operator,
the `try` operator must appear first.

<!--
  The "try await" ordering is also part of the grammar for 'expression',
  but it's important enough to be worth re-stating in prose.
-->

> Grammar of an await expression:
>
> *await-operator* → **`await`**

## Infix Expressions

*Infix expressions* combine
an infix binary operator with the expression that it takes
as its left- and right-hand arguments.
It has the following form:

```swift
<#left-hand argument#> <#operator#> <#right-hand argument#>
```

For information about the behavior of these operators,
see <doc:BasicOperators> and <doc:AdvancedOperators>.

For information about the operators provided by the Swift standard library,
see [Operator Declarations](https://developer.apple.com/documentation/swift/operator_declarations).

<!--
  You have essentially expression sequences here, and within it are
  parts of the expressions.  We're calling them "expressions" even
  though they aren't what we ordinarily think of as expressions.  We
  have this two-phase thing where we do the expression sequence parsing
  which gives a rough parse tree.  Then after name binding we know
  operator precedence and we do a second phase of parsing that builds
  something that's a more traditional tree.
-->

> Note: At parse time,
> an expression made up of infix operators is represented
> as a flat list.
> This list is transformed into a tree
> by applying operator precedence.
> For example, the expression `2 + 3 * 5`
> is initially understood as a flat list of five items,
> `2`, `+`, `3`, `*`, and `5`.
> This process transforms it into the tree (2 + (3 * 5)).

> Grammar of an infix expression:
>
> *infix-expression* → *infix-operator* *prefix-expression* \
> *infix-expression* → *assignment-operator* *try-operator*_?_ *await-operator*_?_ *prefix-expression* \
> *infix-expression* → *conditional-operator* *try-operator*_?_ *await-operator*_?_ *prefix-expression* \
> *infix-expression* → *type-casting-operator* \
> *infix-expressions* → *infix-expression* *infix-expressions*_?_

### Assignment Operator

The *assignment operator* sets a new value
for a given expression.
It has the following form:

```swift
<#expression#> = <#value#>
```

The value of the *expression*
is set to the value obtained by evaluating the *value*.
If the *expression* is a tuple,
the *value* must be a tuple
with the same number of elements.
(Nested tuples are allowed.)
Assignment is performed from each part of the *value*
to the corresponding part of the *expression*.
For example:

```swift
(a, _, (b, c)) = ("test", 9.45, (12, 3))
// a is "test", b is 12, c is 3, and 9.45 is ignored
```

<!--
  - test: `assignmentOperator`

  ```swifttest
  >> var (a, _, (b, c)) = ("test", 9.45, (12, 3))
  -> (a, _, (b, c)) = ("test", 9.45, (12, 3))
  /> a is \"\(a)\", b is \(b), c is \(c), and 9.45 is ignored
  </ a is "test", b is 12, c is 3, and 9.45 is ignored
  ```
-->

The assignment operator doesn't return any value.

> Grammar of an assignment operator:
>
> *assignment-operator* → **`=`**

### Ternary Conditional Operator

The *ternary conditional operator* evaluates to one of two given values
based on the value of a condition.
It has the following form:

```swift
<#condition#> ? <#expression used if true#> : <#expression used if false#>
```

If the *condition* evaluates to `true`,
the conditional operator evaluates the first expression
and returns its value.
Otherwise, it evaluates the second expression
and returns its value.
The unused expression isn't evaluated.

For an example that uses the ternary conditional operator,
see <doc:BasicOperators#Ternary-Conditional-Operator>.

> Grammar of a conditional operator:
>
> *conditional-operator* → **`?`** *expression* **`:`**

### Type-Casting Operators

There are four type-casting operators:
the `is` operator,
the `as` operator,
the `as?` operator,
and the `as!` operator.

They have the following form:

```swift
<#expression#> is <#type#>
<#expression#> as <#type#>
<#expression#> as? <#type#>
<#expression#> as! <#type#>
```

The `is` operator checks at runtime whether the *expression*
can be cast to the specified *type*.
It returns `true` if the *expression* can be cast to the specified *type*;
otherwise, it returns `false`.

<!--
  - test: `triviallyTrueIsAndAs`

  ```swifttest
  -> assert("hello" is String)
  -> assert(!("hello" is Int))
  !$ warning: 'is' test is always true
  !! assert("hello" is String)
  !!                ^
  !$ warning: cast from 'String' to unrelated type 'Int' always fails
  !! assert(!("hello" is Int))
  !!          ~~~~~~~ ^  ~~~
  ```
-->

<!--
  - test: `is-operator-tautology`

  ```swifttest
  -> class Base {}
  -> class Subclass: Base {}
  -> var s = Subclass()
  -> var b = Base()

  -> assert(s is Base)
  !$ warning: 'is' test is always true
  !! assert(s is Base)
  !!          ^
  ```
-->

The `as` operator performs a cast
when it's known at compile time
that the cast always succeeds,
such as upcasting or bridging.
Upcasting lets you use an expression as an instance of its type's supertype,
without using an intermediate variable.
The following approaches are equivalent:

```swift
func f(_ any: Any) { print("Function for Any") }
func f(_ int: Int) { print("Function for Int") }
let x = 10
f(x)
// Prints "Function for Int".

let y: Any = x
f(y)
// Prints "Function for Any".

f(x as Any)
// Prints "Function for Any".
```

<!--
  - test: `explicit-type-with-as-operator`

  ```swifttest
  -> func f(_ any: Any) { print("Function for Any") }
  -> func f(_ int: Int) { print("Function for Int") }
  -> let x = 10
  -> f(x)
  <- Function for Int

  -> let y: Any = x
  -> f(y)
  <- Function for Any

  -> f(x as Any)
  <- Function for Any
  ```
-->

Bridging lets you use an expression of
a Swift standard library type such as `String`
as its corresponding Foundation type such as `NSString`
without needing to create a new instance.
For more information on bridging,
see [Working with Foundation Types](https://developer.apple.com/documentation/swift/imported_c_and_objective_c_apis/working_with_foundation_types).

The `as?` operator
performs a conditional cast of the *expression*
to the specified *type*.
The `as?` operator returns an optional of the specified *type*.
At runtime, if the cast succeeds,
the value of *expression* is wrapped in an optional and returned;
otherwise, the value returned is `nil`.
If casting to the specified *type*
is guaranteed to fail or is guaranteed to succeed,
a compile-time error is raised.

The `as!` operator performs a forced cast of the *expression* to the specified *type*.
The `as!` operator returns a value of the specified *type*, not an optional type.
If the cast fails, a runtime error is raised.
The behavior of `x as! T` is the same as the behavior of `(x as? T)!`.

For more information about type casting
and to see examples that use the type-casting operators,
see <doc:TypeCasting>.

> Grammar of a type-casting operator:
>
> *type-casting-operator* → **`is`** *type* \
> *type-casting-operator* → **`as`** *type* \
> *type-casting-operator* → **`as`** **`?`** *type* \
> *type-casting-operator* → **`as`** **`!`** *type*

## Primary Expressions

*Primary expressions*
are the most basic kind of expression.
They can be used as expressions on their own,
and they can be combined with other tokens
to make prefix expressions, infix expressions, and postfix expressions.

> Grammar of a primary expression:
>
> *primary-expression* → *identifier* *generic-argument-clause*_?_ \
> *primary-expression* → *literal-expression* \
> *primary-expression* → *self-expression* \
> *primary-expression* → *superclass-expression* \
> *primary-expression* → *conditional-expression* \
> *primary-expression* → *closure-expression* \
> *primary-expression* → *parenthesized-expression* \
> *primary-expression* → *tuple-expression* \
> *primary-expression* → *implicit-member-expression* \
> *primary-expression* → *wildcard-expression* \
> *primary-expression* → *macro-expansion-expression* \
> *primary-expression* → *key-path-expression* \
> *primary-expression* → *selector-expression* \
> *primary-expression* → *key-path-string-expression*

<!--
  NOTE: One reason for breaking primary expressions out of postfix
  expressions is for exposition -- it makes it easier to organize the
  prose surrounding the production rules.
-->

<!--
  TR: Is a generic argument clause allowed
  after an identifier in expression context?
  It seems like that should only occur when an identifier
  is a *type* identifier.
-->

### Literal Expression

A *literal expression* consists of
either an ordinary literal (such as a string or a number),
an array or dictionary literal,
or a playground literal.

> Note:
> Prior to Swift 5.9,
> the following special literals were recognized:
> `#column`,
> `#dsohandle`,
> `#fileID`,
> `#filePath`,
> `#file`,
> `#function`,
> and `#line`.
> These are now implemented as macros in the Swift standard library:
> [`column()`](https://developer.apple.com/documentation/swift/column()),
> [`dsohandle()`](https://developer.apple.com/documentation/swift/dsohandle()),
> [`fileID()`](https://developer.apple.com/documentation/swift/fileID()),
> [`filePath()`](https://developer.apple.com/documentation/swift/filePath()),
> [`file()`](https://developer.apple.com/documentation/swift/file()),
> [`function()`](https://developer.apple.com/documentation/swift/function()),
> and [`line()`](https://developer.apple.com/documentation/swift/line()).

<!--
  - test: `pound-file-flavors`

  ```swifttest
  >> print(#file == #filePath)
  << true
  >> print(#file == #fileID)
  << false
  ```
-->

An *array literal* is
an ordered collection of values.
It has the following form:

```swift
[<#value 1#>, <#value 2#>, <#...#>]
```

The last expression in the array can be followed by an optional comma.
The value of an array literal has type `[T]`,
where `T` is the type of the expressions inside it.
If there are expressions of multiple types,
`T` is their closest common supertype.
Empty array literals are written using an empty
pair of square brackets and can be used to create an empty array of a specified type.

```swift
var emptyArray: [Double] = []
```

<!--
  - test: `array-literal-brackets`

  ```swifttest
  -> var emptyArray: [Double] = []
  ```
-->

A *dictionary literal* is
an unordered collection of key-value pairs.
It has the following form:

```swift
[<#key 1#>: <#value 1#>, <#key 2#>: <#value 2#>, <#...#>]
```

The last expression in the dictionary can be followed by an optional comma.
The value of a dictionary literal has type `[Key: Value]`,
where `Key` is the type of its key expressions
and `Value` is the type of its value expressions.
If there are expressions of multiple types,
`Key` and `Value` are the closest common supertype
for their respective values.
An empty dictionary literal is written as
a colon inside a pair of brackets (`[:]`)
to distinguish it from an empty array literal.
You can use an empty dictionary literal to create an empty dictionary literal
of specified key and value types.

```swift
var emptyDictionary: [String: Double] = [:]
```

<!--
  - test: `dictionary-literal-brackets`

  ```swifttest
  -> var emptyDictionary: [String: Double] = [:]
  ```
-->

A *playground literal*
is used by Xcode to create an interactive representation
of a color, file, or image within the program editor.
Playground literals in plain text outside of Xcode
are represented using a special literal syntax.

For information on using playground literals in Xcode,
see [Add a color, file, or image literal](https://help.apple.com/xcode/mac/current/#/dev4c60242fc)
in Xcode Help.

> Grammar of a literal expression:
>
> *literal-expression* → *literal* \
> *literal-expression* → *array-literal* | *dictionary-literal* | *playground-literal*
>
> *array-literal* → **`[`** *array-literal-items*_?_ **`,`**_?_ **`]`** \
> *array-literal-items* → *array-literal-item* | *array-literal-item* **`,`** *array-literal-items* \
> *array-literal-item* → *expression*
>
> *dictionary-literal* → **`[`** *dictionary-literal-items* **`,`**_?_ **`]`** | **`[`** **`:`** **`]`** \
> *dictionary-literal-items* → *dictionary-literal-item* | *dictionary-literal-item* **`,`** *dictionary-literal-items* \
> *dictionary-literal-item* → *expression* **`:`** *expression*
>
> *playground-literal* → **`#colorLiteral`** **`(`** **`red`** **`:`** *expression* **`,`** **`green`** **`:`** *expression* **`,`** **`blue`** **`:`** *expression* **`,`** **`alpha`** **`:`** *expression* **`)`** \
> *playground-literal* → **`#fileLiteral`** **`(`** **`resourceName`** **`:`** *expression* **`)`** \
> *playground-literal* → **`#imageLiteral`** **`(`** **`resourceName`** **`:`** *expression* **`)`**

### Self Expression

The `self` expression is an explicit reference to the current type
or instance of the type in which it occurs.
It has the following forms:

```swift
self
self.<#member name#>
self[<#subscript index#>]
self(<#initializer arguments#>)
self.init(<#initializer arguments#>)
```

<!--
  TODO: Come back and explain the second to last form (i.e., self(arg: value)).
-->

In an initializer, subscript, or instance method, `self` refers to the current
instance of the type in which it occurs. In a type method,
`self` refers to the current type in which it occurs.

The `self` expression is used to specify scope when accessing members,
providing disambiguation when there's
another variable of the same name in scope,
such as a function parameter.
For example:

```swift
class SomeClass {
    var greeting: String
    init(greeting: String) {
        self.greeting = greeting
    }
}
```

<!--
  - test: `self-expression`

  ```swifttest
  -> class SomeClass {
         var greeting: String
         init(greeting: String) {
             self.greeting = greeting
         }
     }
  ```
-->

In a mutating method of a value type,
you can assign a new instance of that value type to `self`.
For example:

```swift
struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        self = Point(x: x + deltaX, y: y + deltaY)
    }
}
```

<!--
  - test: `self-expression`

  ```swifttest
  -> struct Point {
        var x = 0.0, y = 0.0
        mutating func moveBy(x deltaX: Double, y deltaY: Double) {
           self = Point(x: x + deltaX, y: y + deltaY)
        }
     }
  >> var somePoint = Point(x: 1.0, y: 1.0)
  >> somePoint.moveBy(x: 2.0, y: 3.0)
  >> print("The point is now at (\(somePoint.x), \(somePoint.y))")
  << The point is now at (3.0, 4.0)
  ```
-->

<!-- Apple Books screenshot begins here. -->

> Grammar of a self expression:
>
> *self-expression* → **`self`** | *self-method-expression* | *self-subscript-expression* | *self-initializer-expression*
>
> *self-method-expression* → **`self`** **`.`** *identifier* \
> *self-subscript-expression* → **`self`** **`[`** *function-call-argument-list* **`]`** \
> *self-initializer-expression* → **`self`** **`.`** **`init`**

### Superclass Expression

A *superclass expression* lets a class
interact with its superclass.
It has one of the following forms:

```swift
super.<#member name#>
super[<#subscript index#>]
super.init(<#initializer arguments#>)
```

The first form is used to access a member of the superclass.
The second form is used to access the superclass's subscript implementation.
The third form is used to access an initializer of the superclass.

Subclasses can use a superclass expression
in their implementation of members, subscripting, and initializers
to make use of the implementation in their superclass.

> Grammar of a superclass expression:
>
> *superclass-expression* → *superclass-method-expression* | *superclass-subscript-expression* | *superclass-initializer-expression*
>
> *superclass-method-expression* → **`super`** **`.`** *identifier* \
> *superclass-subscript-expression* → **`super`** **`[`** *function-call-argument-list* **`]`** \
> *superclass-initializer-expression* → **`super`** **`.`** **`init`**

### Conditional Expression

A *conditional expression* evaluates to one of several given values
based on the value of a condition.
It has one the following forms:

```swift
if <#condition 1#> {
   <#expression used if condition 1 is true#>
} else if <#condition 2#> {
   <#expression used if condition 2 is true#>
} else {
   <#expression used if both conditions are false#>
}

switch <#expression#> {
case <#pattern 1#>:
    <#expression 1#>
case <#pattern 2#> where <#condition#>:
    <#expression 2#>
default:
    <#expression 3#>
}
```

A conditional expression
has the same behavior and syntax as an `if` statement or a `switch` statement,
except for the differences that the paragraphs below describe.

A conditional expression appears only in the following contexts:

  - As the value assigned to a variable.
  - As the initial value in a variable or constant declaration.
  - As the error thrown by a `throw` expression.
  - As the value returned by a function, closure, or property getter.
  - As the value inside a branch of a conditional expression.

The branches of a conditional expression are exhaustive,
ensuring that the expression always produces a value
regardless of the condition.
This means each `if` branch needs a corresponding `else` branch.

Each branch contains either a single expression,
which is used as the value for the conditional expression
when that branch's conditional is true,
a `throw` statement,
or a call to a function that never returns.

Each branch must produce a value of the same type.
Because type checking of each branch is independent,
you sometimes need to specify the value's type explicitly,
like when branches include different kinds of literals,
or when a branch's value is `nil`.
When you need to provide this information,
add a type annotation to the variable that the result is assigned to,
or add an `as` cast to the branches' values.

```swift
let number: Double = if someCondition { 10 } else { 12.34 }
let number = if someCondition { 10 as Double } else { 12.34 }
```

Inside a result builder,
conditional expressions can appear
only as the initial value of a variable or constant.
This behavior means when you write `if` or `switch` in a result builder ---
outside of a variable or constant declaration ---
that code is understood as a branch statement
and one of the result builder's methods transforms that code.

Don't put a conditional expression in a `try` expression,
even if one of the branches of a conditional expression is throwing.

> Grammar of a conditional expression:
>
> *conditional-expression* → *if-expression* | *switch-expression*
>
> *if-expression* → **`if`** *condition-list* **`{`** *statement* **`}`** *if-expression-tail* \
> *if-expression-tail* → **`else`** *if-expression* \
> *if-expression-tail* → **`else`** **`{`** *statement* **`}`**
>
> *switch-expression* → **`switch`** *expression* **`{`** *switch-expression-cases* **`}`** \
> *switch-expression-cases* → *switch-expression-case* *switch-expression-cases*_?_ \
> *switch-expression-case* → *case-label* *statement* \
> *switch-expression-case* → *default-label* *statement*

### Closure Expression

A *closure expression* creates a closure,
also known as a *lambda* or an *anonymous function*
in other programming languages.
Like a function declaration,
a closure contains statements,
and it captures constants and variables from its enclosing scope.
It has the following form:

```swift
{ (<#parameters#>) -> <#return type#> in
   <#statements#>
}
```

The *parameters* have the same form
as the parameters in a function declaration,
as described in <doc:Declarations#Function-Declaration>.

Writing `throws` or `async` in a closure expression
explicitly marks a closure as throwing or asynchronous.

```swift
{ (<#parameters#>) async throws -> <#return type#> in
   <#statements#>
}
```

If the body of a closure includes a `throws` statement or a `try` expression
that isn't nested inside of a `do` statement with exhaustive error handling,
the closure is understood to be throwing.
If a throwing closure throws errors of only a single type,
the closure is understood as throwing that error type;
otherwise, it's understood as throwing `any Error`.
Likewise, if the body includes an `await` expression,
it's understood to be asynchronous.

There are several special forms
that allow closures to be written more concisely:

<!-- Apple Books screenshot ends here. -->

- A closure can omit the types
  of its parameters, its return type, or both.
  If you omit the parameter names and both types,
  omit the `in` keyword before the statements.
  If the omitted types can't be inferred,
  a compile-time error is raised.
- A closure may omit names for its parameters.
  Its parameters are then implicitly named
  `$` followed by their position:
  `$0`, `$1`, `$2`, and so on.
- A closure that consists of only a single expression
  is understood to return the value of that expression.
  The contents of this expression are also considered
  when performing type inference on the surrounding expression.

The following closure expressions are equivalent:

```swift
myFunction { (x: Int, y: Int) -> Int in
    return x + y
}

myFunction { x, y in
    return x + y
}

myFunction { return $0 + $1 }

myFunction { $0 + $1 }
```

<!--
  - test: `closure-expression-forms`

  ```swifttest
  >> func myFunction(f: (Int, Int) -> Int) {}
  -> myFunction { (x: Int, y: Int) -> Int in
         return x + y
     }

  -> myFunction { x, y in
         return x + y
     }

  -> myFunction { return $0 + $1 }

  -> myFunction { $0 + $1 }
  ```
-->

For information about passing a closure as an argument to a function,
see <doc:Expressions#Function-Call-Expression>.

Closure expressions can be used
without being stored in a variable or constant,
such as when you immediately use a closure as part of a function call.
The closure expressions passed to `myFunction` in code above are
examples of this kind of immediate use.
As a result,
whether a closure expression is escaping or nonescaping depends
on the surrounding context of the expression.
A closure expression is nonescaping
if it's called immediately
or passed as a nonescaping function argument.
Otherwise, the closure expression is escaping.

For more information about escaping closures, see <doc:Closures#Escaping-Closures>.

#### Capture Lists

By default, a closure expression captures
constants and variables from its surrounding scope
with strong references to those values.
You can use a *capture list* to explicitly control
how values are captured in a closure.

A capture list is written as a comma-separated list of expressions
surrounded by square brackets,
before the list of parameters.
If you use a capture list, you must also use the `in` keyword,
even if you omit the parameter names, parameter types, and return type.
The last expression in the capture list can be followed by an optional comma.

The entries in the capture list are initialized
when the closure is created.
For each entry in the capture list,
a constant is initialized
to the value of the constant or variable that has the same name
in the surrounding scope.
For example in the code below,
`a` is included in the capture list but `b` is not,
which gives them different behavior.

```swift
var a = 0
var b = 0
let closure = { [a] in
 print(a, b)
}

a = 10
b = 10
closure()
// Prints "0 10".
```

<!--
  - test: `capture-list-value-semantics`

  ```swifttest
  -> var a = 0
  -> var b = 0
  -> let closure = { [a] in
      print(a, b)
  }

  -> a = 10
  -> b = 10
  -> closure()
  <- 0 10
  ```
-->

There are two different things named `a`,
the variable in the surrounding scope
and the constant in the closure's scope,
but only one variable named `b`.
The `a` in the inner scope is initialized
with the value of the `a` in the outer scope
when the closure is created,
but their values aren't connected in any special way.
This means that a change to the value of `a` in the outer scope
doesn't affect the value of `a` in the inner scope,
nor does a change to `a` inside the closure
affect the value of `a` outside the closure.
In contrast, there's only one variable named `b` ---
the `b` in the outer scope ---
so changes from inside or outside the closure are visible in both places.

<!--
  [Contributor 6004] also describes the distinction as
  "capturing the variable, not the value"
  but he notes that we don't have a rigorous definition of
  capturing a variable in Swift
  (unlike some other languages)
  so that description's not likely to be very helpful for developers.
-->

This distinction isn't visible
when the captured variable's type has reference semantics.
For example,
there are two things named `x` in the code below,
a variable in the outer scope and a constant in the inner scope,
but they both refer to the same object
because of reference semantics.

```swift
class SimpleClass {
    var value: Int = 0
}
var x = SimpleClass()
var y = SimpleClass()
let closure = { [x] in
    print(x.value, y.value)
}

x.value = 10
y.value = 10
closure()
// Prints "10 10".
```

<!--
  - test: `capture-list-reference-semantics`

  ```swifttest
  -> class SimpleClass {
         var value: Int = 0
     }
  -> var x = SimpleClass()
  -> var y = SimpleClass()
  -> let closure = { [x] in
         print(x.value, y.value)
     }

  -> x.value = 10
  -> y.value = 10
  -> closure()
  <- 10 10
  ```
-->

<!--
  - test: `capture-list-with-commas`

  ```swifttest
  -> var x = 100
  -> var y = 7
  -> var f: () -> Int = { [x, y] in x+y }
  >> let r0 = f()
  >> assert(r0 == 107)
  ```
-->

<!--
  It's not an error to capture things that aren't included in the capture list,
  although maybe it should be.  See also rdar://17024367.
-->

<!--
  - test: `capture-list-is-not-exhaustive`

  ```swifttest
  -> var x = 100
     var y = 7
     var f: () -> Int = { [x] in x }
     var g: () -> Int = { [x] in x+y }

  -> let r0 = f()
  -> assert(r0 == 100)
  -> let r1 = g()
  -> assert(r1 == 107)
  ```
-->

If the type of the expression's value is a class,
you can mark the expression in a capture list
with `weak` or `unowned` to capture a weak or unowned reference
to the expression's value.

```swift
myFunction { print(self.title) }                    // implicit strong capture
myFunction { [self] in print(self.title) }          // explicit strong capture
myFunction { [weak self] in print(self!.title) }    // weak capture
myFunction { [unowned self] in print(self.title) }  // unowned capture
```

<!--
  - test: `closure-expression-weak`

  ```swifttest
  >> func myFunction(f: () -> Void) { f() }
  >> class C {
  >> let title = "Title"
  >> func method() {
  -> myFunction { print(self.title) }                    // implicit strong capture
  -> myFunction { [self] in print(self.title) }          // explicit strong capture
  -> myFunction { [weak self] in print(self!.title) }    // weak capture
  -> myFunction { [unowned self] in print(self.title) }  // unowned capture
  >> } }
  >> C().method()
  << Title
  << Title
  << Title
  << Title
  ```
-->

You can also bind an arbitrary expression
to a named value in a capture list.
The expression is evaluated when the closure is created,
and the value is captured with the specified strength.
For example:

```swift
// Weak capture of "self.parent" as "parent"
myFunction { [weak parent = self.parent] in print(parent!.title) }
```

<!--
  - test: `closure-expression-capture`

  ```swifttest
  >> func myFunction(f: () -> Void) { f() }
  >> class P { let title = "Title" }
  >> class C {
  >> let parent = P()
  >> func method() {
  // Weak capture of "self.parent" as "parent"
  -> myFunction { [weak parent = self.parent] in print(parent!.title) }
  >> } }
  >> C().method()
  << Title
  ```
-->

For more information and examples of closure expressions,
see <doc:Closures#Closure-Expressions>.
For more information and examples of capture lists,
see <doc:AutomaticReferenceCounting#Resolving-Strong-Reference-Cycles-for-Closures>.

<!--
  - test: `async-throwing-closure-syntax`

  ```swifttest
  >> var a = 12
  >> let c1 = { [a] in return a }                  // OK: No async or throws
  >> let c2 = { [a] async in return a }            // Error
  >> let c3 = { [a] async -> in return a }         // Error
  >> let c4 = { [a] () async -> Int in return a }  // OK: Has () and ->
  !$ error: expected expression
  !! let c3 = { [a] async -> in return a }         // Error
  !! ^
  !$ error: unable to infer type of a closure parameter 'async' in the current context
  !! let c2 = { [a] async in return a }            // Error
  !! ^
  // NOTE: The error message for c3 gets printed by the REPL before the c2 error.
  ```
-->

> Grammar of a closure expression:
>
> *closure-expression* → **`{`** *attributes*_?_ *closure-signature*_?_ *statements*_?_ **`}`**
>
> *closure-signature* → *capture-list*_?_ *closure-parameter-clause* **`async`**_?_ *throws-clause*_?_ *function-result*_?_ **`in`** \
> *closure-signature* → *capture-list* **`in`**
>
> *closure-parameter-clause* → **`(`** **`)`** | **`(`** *closure-parameter-list* **`,`**_?_ **`)`** | *identifier-list* \
> *closure-parameter-list* → *closure-parameter* | *closure-parameter* **`,`** *closure-parameter-list* \
> *closure-parameter* → *closure-parameter-name* *type-annotation*_?_ \
> *closure-parameter* → *closure-parameter-name* *type-annotation* **`...`** \
> *closure-parameter-name* → *identifier*
>
> *capture-list* → **`[`** *capture-list-items* **`,`**_?_ **`]`** \
> *capture-list-items* → *capture-list-item* | *capture-list-item* **`,`** *capture-list-items* \
> *capture-list-item* → *capture-specifier*_?_ *identifier* \
> *capture-list-item* → *capture-specifier*_?_ *identifier* **`=`** *expression* \
> *capture-list-item* → *capture-specifier*_?_ *self-expression* \
> *capture-specifier* → **`weak`** | **`unowned`** | **`unowned(safe)`** | **`unowned(unsafe)`**

### Implicit Member Expression

An *implicit member expression*
is an abbreviated way to access a member of a type,
such as an enumeration case or a type method,
in a context where type inference
can determine the implied type.
It has the following form:

```swift
.<#member name#>
```

For example:

```swift
var x = MyEnumeration.someValue
x = .anotherValue
```

<!--
  - test: `implicitMemberEnum`

  ```swifttest
  >> enum MyEnumeration { case someValue, anotherValue }
  -> var x = MyEnumeration.someValue
  -> x = .anotherValue
  ```
-->

If the inferred type is an optional,
you can also use a member of the non-optional type
in an implicit member expression.

```swift
var someOptional: MyEnumeration? = .someValue
```

<!--
  - test: `implicitMemberEnum`

  ```swifttest
  -> var someOptional: MyEnumeration? = .someValue
  ```
-->

Implicit member expressions can be follo

…(truncated)
