Back to blog

Functions in Swift Explained


Aasif Khan
By Aasif Khan | Last Updated on August 2nd, 2023 1:15 pm | 4-min read

In Swift you use functions to perform specific tasks in your code. It’s that simple! Functions can take input and produce output. They are particularly useful for creating a reusable tasks and actions in your code.

Knowing how functions work is one of the first steps of learning iOS development. In this app development tutorial you’ll learn:

  • How to use define and use functions in Swift
  • What function parameters and its return type are
  • How to write functions that take input and produce output
  • The difference between an argument and a parameter
  • Why functions are essential for practical iOS development

How To Define and Call Functions in Swift

The Swift Programming Language guide includes a terrific description of what a function is:

Functions are self-contained chunks of code that perform a specific task

Functions are small pieces of code that you can execute by calling the function’s name. A function takes input parameters and can produce an output value. Functions are useful for creating reusable tasks or actions in your code.

Let’s take a look at analogy. Imagine you’re playing chess and you’re about to move the rook piece. Like this:

moveForward(piece: rook, steps: 5)

This is an example of a function call. You are using the moveForward(piece:steps:) function to move the rook object 5 steps forward.

In the above example, rook is a variable. You can learn more about variables in Swift here.

Working with a function in Swift has two parts:

  1. Defining the function
  2. Calling the function

You define a function before calling it, as if you’re preparing a task before performing it. You can call a function many times. This is the basis for a concept called abstraction.

Imagine that your chess game has many functions, like setupBoard(), validateMove() and isCheckmate(). Instead of writing every scenario within the chess game manually, you use abstractions to repeat common tasks, like validating a chess move or checking if a player has caused a checkmate. Code is built from these abstractions, like the huge stones that make up an Egyptian pyramid.

Let’s look at an example.

func moveForward(piece: String, steps: Int)
{
print(“Moving the \(piece) piece \(steps) steps forward…”)
}

moveForward(piece: “Queen”, steps: 3)

Here’s what happens:

  1. A function is defined with func moveForward(piece: String , starting on the first line
  2. That function is called with moveForward(piece: “Queen”, steps: 3) on the last line

Let’s go over the function definition first. Here’s how it works:

  • func is the keyword you use to start a function declaration
  • moveForward is the name of the function
  • (piece:String, steps:Int) are the function’s parameters
  • piece is the function’s first parameter name, and String is its type
  • steps is the function’s second parameter name, and Int is its type
  • between the squiggly brackets { and } goes the function body

The most important parts are the function name, its parameters and the function body. The function name describes the task that the function can perform, and its parameters describe what kind of input the function expects.

The function body contains the code of the function, i.e. the code that’s executed when the function is called. The function prints a simple line of text in the above example.

You can imagine that, in a chess app, the real function body of moveForward() validates the move, changes the position of the chess piece, and potentially captures another chess piece. In the above code, we’re just printing some text.

Back to the function call. That last line, in the previous example, is the function call. Like this:

moveForward(piece: “Queen”, steps: 3)

You provide the function with arguments, i.e. “Queen” and 3. This is the actual input for the function. (More on arguments and parameters later.)

A function call essentially executes the code within the function body. The cool thing about functions is that you can call them multiple times, while defining the function only once. Like this:

moveForward(piece: “Queen”, steps: 3)
moveForward(piece: “Rook”, steps: 5)
moveForward(piece: “Pawn”, steps: 1)

Inside the function you’d write code to perform allowed moves for different pieces. Instead of coding every move manually, you create an abstraction that can perform multiple moves. Abstraction is a powerful principle!

Function Arguments and Parameters

A function can have zero, one or more parameters. A parameter is input for a function. Let’s look at an example:

func greeting(user: String)
{
print(“Hello, \(user). How are you?”)
}

greeting(user: “Arthur”)

In the above code, user is a parameter of the function greeting(user:). The parameter is used as input for the function, so the function can “greet” the user.

Function parameters are written after the function name, and wrapped in parentheses. Multiple function parameters are separated with commas. Some examples:

func setupBoard()
func greeting(user: String)
func compare(a: String, b: String)

When calling a function in Swift you always have to write the parameter name, unless otherwise specified, like this:

greeting(user: “Arthur”)

That “Arthur” is called an argument. This is a point of confusion for many beginner developers. What is the difference between a parameter and an argument?

  • When defining a function, you define parameters. Within the function body you can use the parameters as local variables, like user in the previous example.
  • When calling a function, you provide arguments within the function call. This is the value that’s assigned to the parameter, and the input for the function.

A helpful mnemonic is:

A parameter is the “parking spot”. An argument is the “car” you park in the “parking spot”.

In practical iOS development, you’ll often simply call it a parameter. I don’t like making things more complicated than they are, so you’ll often see me calling input for a function a parameter (even though “argument” would be correct).

There’s one more thing we need to get into before continuing: argument labels and parameter names. Consider the following function:

func authenticateUser(withUsername username:String, andPassword password: String)
{
print(“Authenticating \(username) with password ***”)
}

authenticateUser(withUsername: “Zaphod”, andPassword: “h3art0fg0ld”)

OK, now check the parameters and arguments for this function. You see withUsername and username, and andPassword and password in the function definition. You also see withUsername and andPassword in the function call, on the last line. What’s that about?

In the function definition, withUsername is an argument label and username is a parameter name. When a parameter has an argument label, you use the argument label instead of the parameter name when calling that function.

The difference is important, because using argument labels is fairly common in practical iOS development. Many Cocoa Touch SDKs use argument labels to make functions more descriptive.

You use the argument label when calling the function. It’s an extra description for the function’s arguments. Within the function, you just use the shorter parameter name. If a function parameter doesn’t have an argument label, you’ll just use the parameter name for both.

Why use argument labels, though?

Argument labels, i.e. the extra stuff that’s part of the function definition, are used to make functions more descriptive. It also helps with talking about a function, i.e. “authenticate user with username and password” as opposed to “authenticate username password”. Within the function you use the parameter name, because that’s shorter and looks more like an actual variable name. Working with argument labels in Swift is also just what we’re used to; a convention.

Don’t want to use parameter names at all? Simply prepend a function parameter with an underscore, like this: func pow(_ a:Int, _ b:Int) { . You can then call that function without labels, like this: pow(2, 4).

Function Return Types and Values

Just as functions have input, they also have output. It’s only logical that functions produce some output value!

A function in Swift can define a return type. Like this:

func abs(_ a: Int) -> Int
{
if a < 0 { return a * -1 } return a } let result = abs(-11) print(result) In the above example, the -> Int indicates the return type. You specify that this function will return a value of Int. The -> syntax is a hyphen followed by a right angle bracket, i.e. a “single arrow”.

Within the function a value is returned with the return keyword. This will halt execution of the function at that point, and return the value of an expression.

In the above function …

  • … a * -1 is returned when a is smaller than zero
  • … and if not, a is simply returned

As you would expect from an abs() function, this effectively returns the absolute value of a. The function always returns a positive integer.

The return value of a function doesn’t need to be the only result a function produces. For instance, a function can write data to a database, and return true if that operation has succeeded.

In Swift, the output of a function is provided to whomever calls it. You see that in the above example, the value of abs(-11) is assigned to the constant result. Like this:

let result = abs(-11)

You can also use the output of one function as input for another. Like this:

print(abs(-11))

Functions can be used in expressions, too. Like this:

let result = abs(11) + abs(-11)

Functions are first-class citizens in Swift, which means you can call them anywhere, as if it’s a variable. You can create expressions from functions, just as you can create expressions with variables and literals.

Here’s another cool example:

func fibonacci(_ i: Int) -> Int {
if i <= 2 { return 1 } else { return fibonacci(i - 1) + fibonacci(i - 2) } } for i in 1...10 { print(fibonacci(i)) } The above function uses recursion to calculate the nth value in the Fibonacci sequence. See how the function calls itself? That’s recursion!

Further Reading

Now you know how to define and call functions in Swift. We’ve looked at parameters, arguments and return types. Awesome!

Here’s what we’ve discussed:

  • How to use define and use functions in Swift
  • What function parameters and its return type are
  • How to write functions that take input and produce output
  • Why functions are essential for practical iOS development


Aasif Khan

Head of SEO at Appy Pie

App Builder

Most Popular Posts