Hacking The iOS Interview

Swift — Functions & Closures — Part I

Jayant Kumar Yadav
Hash Coding
Published in
5 min readFeb 23, 2021

--

Photo by Joshua Reddekopp on Unsplash

One of the favourite topics for an interviewer when it comes to finding an interviewee’s swift knowledge. A good grip on functions, closures and higher-order function related concept will provide you with an edge. This discussion would most probably open with a question of the difference between function and closure. Let’s start with the same.

What are functions and closures in swift ?

Functions are a self-contained piece of code that performs a specific task. They are referred to as first-class objects. Every function has a type, consisting of its parameter types and return type, which makes it easy to pass functions as parameters to other functions and to return functions from functions. They can be nested to encapsulate functionalities within other functions.

A combination of a function and an environment of captured variables is called a closure. They can capture and store references to any constants and variables from the context in which they’re defined. This is known as closing over those constants and variables. They are usually unnamed functions.

What is the closure expression ?

There are two ways of creating functions — either with the func keyword or with {}. Swift calls the later closure expressions. {} are a way to write inline functions in a brief, focused syntax. Closure expressions provide several syntax optimizations for writing functions in a shortened form without loss of clarity or intent.

Closure expressions { } can be thought of as function literal in the same way that [ ] and [ : ] are array and dictionary literal.

Here’s an extract from the book Advanced Swift by objc.io

Remember, a closure is a function combined with any captured variables. While functions created with { } are called closure expressions, people often refer to this syntax as just closures. But don’t get confused and think that functions declared with the closure expression syntax are different from other functions — they aren’t. They’re both functions, and they can both be closures.

How closure expressions help brevity in swift ?

They use various compiler level inferences and shorthands to minimize the code to write while maintaining the intent. Let’s take an example of this simple function twice which returns double of its argument.

And here’s the same function is written using the closure expression syntax. Just like before, we can pass it to the map.

Closure expression syntax can be a lot more compact, we can boil down the above statements to its shortest form possible. Remember the rules against each step.

What would be the output of the following code ?

let someFunction = { $0 + $1 }

This will show an error because the compiler is not able to infer the types of parameters. If you want to assign closure expressions to a variable, and the compiler is not able to infer types, this is when you’d have to lock down which specific types it’s operating on. A variable can’t hold a generic function — only a specific one.

let someFunction: (Int, Int) -> Int = { $0 + $1 }

Function parameters are constants by default we can’t mutate them directly. If you haven’t read Swift — let vs var story, then it’s time to pause and have a look.

What is wrong with this code snippet ?

You can only pass a variable as the argument for an in-out parameter. This makes sense because we’re not allowed to mutate let variables.

Line 7 — Cannot pass immutable value as inout argument: ‘currentClaps’ is a ‘let’ constant

Furthermore, in-out is pass-by-value-and-copy-back, not pass-by-reference. They are an alternative way for a function to affect outside of the scope of its body. To quote The Swift Programming Language —

An in-out parameter has a value that’s passed into the function, is modified by the function, and is passed back out of the function to replace the original value.

In-out parameters can’t have default values, and variadic parameters can’t be marked as in-out.

Explain the issues with the below code snippet ?

You can use an inout parameter inside nested functions, but Swift will make sure your usage is safe. For instance, you can define a nested function (either using func or using a closure expression) and safely mutate an inout parameter. However, you’re not allowed to let that inout parameter escape. This makes sense, given that the inout value is copied back just before the function returns. If we could somehow modify it later, what should happen? Should the value get copied back? What if the source no longer exists? Having the compiler verify this is critical for safety.

Line 7Escaping closure captures ‘inout’ parameter ‘claps’

Why argument labels aren’t required in the function call when it is assigned to some variable ?

We must not include an argument label in the addTwoNumbers call, whereas add call requires the argument label. Swift only allows argument labels in function declarations; the labels aren’t included in a function’s type. This means that you currently can’t assign argument labels to a variable of a function type, though this will likely change in a future Swift version.

That’s mostly everything on functions in swift. The next part of this story will revolve around closures and after that one more part on Higher-order functions. Keep following for updates when these parts get published. In case you come across other important question do let me know in the response section.

I hope you find this story helpful. If you liked it, share this with your community and feel free to give your claps below 👏 to help others find it! Thanks for reading.

Get notified every time we post a new story to our publication. Follow us now

We are dedicated to our goal to help every iOS developer grow and give their best in the interview. Every week we’ll be coming up with newer topics. Don’t miss them. Signup Now. ✉️

--

--