I think we’ve gone over the basics of variables in Swift enough. It is time to talk about functions in Swift. Now, we have talked about these to some extent before, and I took it as a given that people would understand a bit. But now I think it is time to actually start diving in and explaining more specifics.
Functions are blocks of code that perform a task. You can then call these functions at different places, which makes fixing bugs much easier than the alternative. If you just copied and pasted the code everywhere, and you found a bug, you would have to change each one to fix that bug. With functions, you just change it one place, and everything that calls it gets the new fixed version of that block of code. The entire app itself is wrapped within a function called “main”, but you don’t normally interact with it, unless there’s a crash. Functions usually take arguments, and very often return data back to where it was called from.
Vocabulary Lesson
There are a few words that I’ll use here that it may be best to have defined outright, so here goes:
- Function Signature (aka Signature): The top line of the function, outside of that function’s curly braces. This describes the inputs, return type, and visibility of a function.
- Parameters: The inputs to a function. These are the variables created in the function signature, for use inside the function to do its job.
- Arguments: Where the parameters come from. When you call a function, and give it the appropriate inputs, these are called arguments.
- Arity: The number of arguments a function takes.
Function parameters
Functions take in data to do their job, usually. There are situations where they don’t, such as to return a random number, or maybe play a sound, or maybe to access something from a global variable, but in general, they take inputs. Functions in Swift can take many different numbers of parameters including zero, one, multiple, or even an unknown number of them (that one is called a Variadic parameter). The current article on Wikipedia about Variadic Functions says that they are functions of indefinite arity. I had never heard of that word before today.
For these examples, I am going to show functions with no return types, just to make the syntax simpler to just demonstrate differences in function parameters. If you want to read about return types, skip ahead to the Return Types for Functions section.
No Parameters
Like I had mentioned, this could be used as something to generate something randomly or do some sort of side effect like toggle something or play a sound. These are the simplest ones. A no parameter function would look like this:
func playBeepNoise()
Very simple, it takes no parameters, and no arguments. Inside of this one, you would probably pass some audio file to a media player or whatnot and just have it play.
One Parameter with No External Name
If you want multiple parameters with no external name, you must use the ” _ ” underscore character as the external name, which is the first label listed for that argument:
func playSpecificBeepNoiseWithDelayOf(_ aNumber: Int, _ filename: String)
Variadic Parameters – Unspecified number of parameters
These are interesting. You can actually create a method that works on any number of parameters, well, any number of the same type. Basically, it will create an array of the values you put in, then you can iterate through them and do whatever you want. You could have a method that sums all the numbers sent into it, or maybe one that puts a bunch of strings together joined by spaces. Basically, you say a value, give it its type, and then add three period characters afterwards to make it a variadic parameter. For example:
func printStringsJoinedWithSpaceAfterEach(words: String...) { var result = "" for word in words { result += word result += " " } print(result) }
You would call it like this:
printStringsJoinedWithSpaceAfterEach(words: "These", "are", "multiple", "words") //Console Output: "These are multiple words "
Whether that exact function is a good idea is inconsequential (and yes, I know there is an extra space at the end), it nonetheless takes as many parameters as you want.
You can have more than just the Variadic parameter in your function prototype, but the variadic parameter must be the last one listed. From Swift 2 onwards, a Variadic parameter can be in any position in the function signature. Prior to it, it could only be put at the end, so now:
func printStringsJoinedWithSpaceAfterEach(aNumber: Int, words: String...) //Is Valid func printStringsJoinedWithSpaceAfterEach(words: String..., aNumber: Int) //Is Also Valid (Since Swift 2)
You also can only have one variadic parameter per function. Apple’s iBook explicitly states that you can only use one variadic parameter per function.
Naming Parameters
It is common in Objective-C to name each of your parameters. While I started showing you how to do it without having to type them when calling, it is often a good idea to have them as part of your call to this function. It makes the code much more understandable (but longer), since you know what each parameter is without having to look up the function. There are two ways to do this.
Use a different External Name
If you want a more descriptive name when calling it, but a shorter name to use internally, you just write the external name before the internal name, like so:
func playBeepNoise(withDelayInMilliseconds msDelay: Int) { print(String(msDelay)) } //Called like this playBeepNoise(withDelayInMilliseconds: 42)
Return Types for Functions
Like function parameters, you can return different amounts. We’ve already seen functions with no return type. Additionally, a function can return one, multiple (known number though, no variadic return types, an array is the closest you get). The multiple return value is called a “tuple”. According to Dictionary.com, both pronunciations of it are valid (too-pull and tuh-pull). Some people suggest that it should be “tuh-pull”, since it is related to words like “quintuple” or “octuple.” I personally like saying “too-pull” myself, but that’s just me.
You can read more about tuples in the post Tuples in Swift: Create, Read, and Return.
Single Return Type
Most programming languages only have one return type, if any. As such, of course it is possible to do so in Swift. I have not personally seen it written like it is in Swift elsewhere, but simple nonetheless:
func addFiveToThisNumber(number: Int) -> Int
You just make that arrow character, which is just a hyphen and a greater-than symbol, and then follow it with the type name.
Multiple Return Types
It sounds like it should be complex, but they really set it up similar to how you set parameters, just on the return type side, so you basically enclose your return types in parenthesis and give each a name and type separated by a comma after that arrow ( -> ), such as:
func addAndSubtractTen(from number: Int) -> (small: Int, large: Int) { let smallResult = (number - 10) let largeResult = (number + 10) return (smallResult, largeResult) }
As you can see, you just return it between parenthesis. You would then use it like this:
let answer = addAndSubtractTen(from: 24) answer.small answer.large
Optional Multiple Return Types
You could also make the whole tuple optional by simply putting a question mark at the end of the return type, like so:
func giveTwoValuesIfValid(input: Int) -> (one: Int, two: Int)?
You would just return nil, instead of something in parenthesis like you normally would when returning a tuple.
Conclusion
Since functions are so important to programming, they definitely need a lot of flexibility to do their job well. Swift has given more flexibility than most languages by letting functions return tuples. This post may be a bit Comp Sci 101, but by doing the research for this I even learned more, like how to write variadic parameters. I also learned the word “arity,” so there are some nuggets of new things hidden amongst the introductory information.
I hope you found this article helpful. If you did, please don’t hesitate to share this post on Twitter or your social media of choice, every share helps. Of course, if you have any questions, don’t hesitate to contact me on the Contact Page, or on Twitter @CodingExplorer, and I’ll see what I can do. Thanks!