iTranslated by AI
Unique Syntax Features: Swift
This article is for day 8 of the Programming Language Specific Syntax Advent Calendar 2025.
I will introduce them based on my personal preferences.
Sample code for binary search
It is implemented specifically using language features.
// Swift - guard + where clause + optional chaining
func binarySearch<T: Comparable>(_ arr: [T], target: T) -> Int? {
var (left, right) = (0, arr.count - 1)
while left <= right {
let mid = (left + right) >> 1
switch arr[mid] {
case let x where x == target: return mid
case let x where x < target: left = mid + 1
default: right = mid - 1
}
}
return nil
}
let arr = [1, 3, 5, 7, 9]
print(binarySearch(arr, target: 5) ?? -1) // 2
Featured Syntax
guard Statement
Explicitly check conditions with early returns and use variables outside the scope.
// Explicitly check conditions with early returns
func process(_ value: Int?) {
guard let value = value else { return }
guard value > 0 else { return }
// value can be used as non-optional
print(value)
}
// Multiple conditions
guard let x = optX, let y = optY, x > y else {
return
}
switch + where Clause
Branching that combines pattern matching with additional conditions.
// Combination of pattern matching and conditions
switch value {
case let x where x < 0: print("negative")
case 0: print("zero")
case let x where x > 0: print("positive")
default: break
}
// Tuple matching
switch (x, y) {
case (0, 0): print("origin")
case (_, 0): print("on x-axis")
case (0, _): print("on y-axis")
case let (x, y) where x == y: print("diagonal")
default: print("other")
}
Optionals
A mechanism for expressing the possibility of a value's absence within the type system.
// Declare with ?, force unwrap with !
var name: String? = nil
name = "Alice"
print(name!) // Force unwrap
// Optional binding
if let name = name {
print(name)
}
// Optional chaining
let length = user?.profile?.name?.count
// Nil-coalescing operator
let displayName = name ?? "anonymous"
Tuples and Decomposition
Allows you to group multiple values to return them or assign them to multiple variables at once.
// Returning multiple values
func minMax(_ arr: [Int]) -> (min: Int, max: Int)? {
guard let first = arr.first else { return nil }
return arr.reduce((first, first)) { ($0.0.min($1), $0.1.max($1)) }
}
// Decomposition assignment
let (min, max) = minMax([1, 2, 3])!
var (left, right) = (0, arr.count - 1)
Trailing Closures
Syntax that allows a closure to be written outside the parentheses when it is the last argument.
// If the last argument is a closure, it can be placed outside
arr.filter { $0 > 0 }
.map { $0 * 2 }
.forEach { print($0) }
// Multiple trailing closures
UIView.animate(withDuration: 0.3) {
view.alpha = 0
} completion: { _ in
view.removeFromSuperview()
}
I personally really like this one.
$0, $1 (Shorthand Argument Names)
Implicit argument names that allow you to write closure arguments more concisely.
// Omit closure arguments
let doubled = arr.map { $0 * 2 }
let sum = arr.reduce(0) { $0 + $1 }
let sorted = arr.sorted { $0 > $1 }
defer
Defines a code block that is guaranteed to be executed when the current scope is exited.
// Always executed when the scope exits
func readFile() {
let file = open("data.txt")
defer { close(file) } // Executed when the function ends
guard let content = read(file) else { return } // defer is executed here as well
process(content)
}
// Multiple defers are executed in reverse order
defer { print("1") }
defer { print("2") } // Output: 2, 1
I felt like readability might drop for a moment, but it seems good for grouping cleanup tasks like resource management.
willSet / didSet (Property Observers)
Allows you to execute code immediately before or after a property's value is changed.
var score: Int = 0 {
willSet { print("Before change: \(score) → \(newValue)") }
didSet { print("After change: \(oldValue) → \(score)") }
}
// Value validation in didSet
var percentage: Int = 0 {
didSet { percentage = min(100, max(0, percentage)) }
}
KeyPath .
Allows references to properties to be treated as first-class objects.
// Treat property references as first-class objects
let names = users.map(\.name) // Same as users.map { $0.name }
let sorted = users.sorted(by: \.age)
// Dynamic property access
struct User { var name: String; var age: Int }
let keyPath: KeyPath<User, String> = \.name
print(user[keyPath: keyPath])
some / any (Opaque Types / Existential Types)
Allows returning a type that conforms to a protocol while hiding the concrete type.
// some: Hides the concrete type (the compiler knows the type)
func makeShape() -> some Shape { Circle() }
// any: Existential type (can mix different types)
var shapes: [any Shape] = [Circle(), Rectangle()]
// Typical usage in SwiftUI
var body: some View {
Text("Hello")
}
@resultBuilder (DSL Builder)
A feature that allows building declarative DSLs (Domain Specific Languages).
// Used in SwiftUI view construction
var body: some View {
VStack {
Text("Hello")
Text("World")
if showButton {
Button("Tap") { }
}
} // Declarative syntax that is neither an array nor a closure
}
A very interesting feature.
Discussion