In This Article
Every program you've written so far has been a straight sequence of statements. That works for learning, but real apps have tasks that happen over and over — fetching data, formatting dates, validating input. Functions let you wrap a task into a named, reusable block. Define it once, call it anywhere, as many times as you need.
Function Basics
Here's the simplest possible function — it takes no input and returns nothing:
The anatomy: func keyword, then the function name, then parentheses (required even when empty), then the body in braces. To run the function, write its name followed by parentheses — this is called calling or invoking the function.
Parameters and Argument Labels
Functions become powerful when they accept input. You declare parameters inside the parentheses:
When calling the function, you must include the parameter label (name:). Swift is designed so that function calls read like sentences.
External vs. internal names
Swift lets you give a parameter two names: an external name (used when calling) and an internal name (used inside the function):
Breaking this down:
_beforenumber— no external label (caller just writes the value)bybeforemultiplier— the caller writesby:, but inside the function you usemultiplier
The call reads naturally: "multiply 4 by 3". This is a core Swift design principle — your code should be readable at the call site.
A parameter is the variable declared in the function definition. An argument is the actual value you pass when calling the function. The function declares parameters; the caller provides arguments.
Default Parameter Values
You can give parameters default values. If the caller doesn't provide a value, the default is used:
Defaults simplify common calls while keeping flexibility for special cases.
Return Values
Functions can send data back to the caller using -> followed by the return type:
For single-expression functions, you can omit the return keyword — Swift returns the expression's value automatically. For multi-line functions, you need an explicit return:
Returning Multiple Values With Tuples
One of Swift's best features: you can return multiple values from a single function using a tuple:
Named tuple members make the return value self-documenting. No need to remember which index is which.
Modifying Parameters With inout
By default, function parameters are constants — you can't modify them. If you need a function to change a value directly, use inout:
The & before the argument signals that this value will be modified. This explicitness is intentional — it makes it obvious at the call site that the function has side effects.
Functions that modify their parameters are harder to reason about. Prefer returning a new value instead. Reserve inout for cases where modifying in place is genuinely clearer or more performant.
Function Overloading
Overloading means defining multiple functions with the same name but different parameter lists:
Swift distinguishes overloaded functions by their parameter count, types, or external names. The right version is chosen automatically based on how you call it.
You can also overload by return type, but this requires explicit type annotations at the call site and is generally not recommended since it loses the benefit of type inference.
Functions as Values
In Swift, functions are just another type. You can assign them to variables, pass them as arguments, and return them from other functions:
The type (Int, Int) -> Int describes a function that takes two integers and returns an integer. Any function matching this signature can be assigned to the variable.
Passing functions to other functions
This is incredibly powerful. Instead of hardcoding what operation to perform, you pass it in as a parameter. This pattern — passing behavior as data — is the foundation of functional programming and shows up everywhere in Swift (closures, higher-order functions on arrays, SwiftUI).
Functions That Never Return
Some functions are designed to never return control to the caller. Swift has a special return type for this: Never.
The built-in fatalError() is the most common example. It prints a message and immediately terminates the program. You'd use this when continuing execution would be dangerous — like processing corrupted data.
The Never return type tells the compiler that code after the call is unreachable, allowing it to generate optimized code and warn you about dead code.
Documenting Your Functions
Good developers document their functions. Swift uses triple-slash (///) comments that integrate with Xcode's code completion:
In Xcode, you can auto-generate this template by placing your cursor on the function and pressing Command-Option-/. The documentation then appears in autocomplete suggestions and Option-click popovers.
Exercises
Try These in Your Playground
- Write a function
printFullName(firstName:lastName:)that prints a full name. Then change it to use_for both parameter labels so the call readsprintFullName("Alex", "Kim"). - Write a function
calculateFullNamethat returns the full name as aString. Then modify it to return a tuple with both the name and its character count. - Write
isNumberDivisible(_ number: Int, by divisor: Int) -> Bool, then use it to writeisPrime(_ number: Int) -> Bool. Test with 6 (false), 13 (true), and 8893 (true). - Write a recursive
fibonacci(_ n: Int) -> Intfunction. Verify: fibonacci(1)=1, fibonacci(5)=5, fibonacci(10)=55. - Write two functions
addandmultiplywith the same signature(Int, Int) -> Int. Assign them to a variable and call it with different operations. - Challenge: Use
stride(from:through:by:)to print a countdown from 10.0 to 0.0, decrementing by 0.5.
Key Points
What You Learned
- Functions are defined with
func, a name, parameters in parentheses, and a body in braces - Parameters have external names (for the caller) and internal names (for the body)
- Use
_to suppress an external parameter name - Default parameter values let callers omit arguments that are usually the same
- Functions return values with
-> Type; single-expression bodies don't needreturn - Tuples let you return multiple values from a single function
- Parameters are constants by default; use
inout(and&at the call site) to modify them - Overloading lets multiple functions share a name with different parameter lists
- Functions are values — you can assign them to variables and pass them as arguments
- The
Neverreturn type indicates a function that doesn't return - Document functions with
///comments for Xcode integration
In the next chapter, we'll explore Optionals — Swift's system for safely handling values that might not exist. This is one of Swift's most important features and the key to writing crash-free code.
Watch the video lessons
Our Swift Fundamentals course covers functions, closures, and advanced patterns in 96 video lessons.
Watch Swift Videos