Argument Labels and Parameter Names
In this article we’re going to talk about Argument Labels and Parameter Names. Before giving some definitions, let’s dive directly into the code to better understand those arguments. Let’s start with a simple function that has the same name for argument label and parameter name.
1
2
3
func greet(person: String) {
print("Hi, \(person)")
}
The function has a parameter called person of type String, that is used inside the function, in its implementation. When we call the function, we use its argument label. Here we’re calling the greet(person:)
function by passing the person argument “Silvio”
1
greet(person: "Silvio")
When we wrote the function we defined the parameter name. In this default situation, the parameter and the argument share the same name: person. When we declare a function and we assing to a parametere a name and a type, we’re in this default situation, where the parameter name and the argument label are the same.
To recap:
- A parameter is used inside the implementation of the function. It’s REQUIRED and must be named in order to be used inside the function.
- An argument label is used when we call the function.
- In a default situation, we can just define the parameter name and the argument label will be implicitly defined with the same name of the parameter.
Omitting the prefix
Swift is a flexible programming language, there are a variety of methods to do the same thing. Let’s continue our example, by using the greet function but this time we’ll explicitly omit the argument label. Before doing that, let’s ask ourself some questions. First of all, what does “omitting argument label” means??? If we omit the argument label for the greet function this means that we can call it like that:
1
greet("James")
It’s immediately obvious that we’re calling the function with its name, but omitting the argument "person"
, passed before, and using just the value “James”. This is a C-style named function. We just pass the value. We should notice that if a function has an argument label, we MUST use that label when we call a function, otherwise we’ll get a compiler error. Try yourself in a Playground, don’t trust me!
So, we know what will be the result of omitting the argument label, but now, how can we do it??? Actually it’s pretty simple: you just have to use the underscore _
before the parameter name, to tell the compiler that you want to omit the argument label.
1
2
3
func greet(_ person: String) {
print("Hi, \(person)")
}
Understand Argument and Parameters it’s all about perspective. We’ve talked about argument label and how we can omit it by using the _ The result is that we can call the function simply by passing the value
1
greet("James")
In this case we were in the perspective of a developer that wants to call our function. So, we’ve seen the function from the outside.
Now let’s change perspective. What changes from the implemenation point of view (from the inside) in a function that has the default argument label and another function that omits the prefix??? NOTHING. Nothing change! In both cases a parameter named person is available, and that’s the only thing that matters from an implementation point of view. You can see that the implementation code hasn’t changed! This concept is important! I think that it can greatly simplify the understanding of argument labels and parameters name.
Argument label
Now, let’s see the third case: we want to specify an argument label. Again, some questions arise:
- How can I define an argument label?
- What changes from the perspective of a developer that wants to call the function?
- What changes from the perspective of the implementation of the fuction?
- Why should I use a specific argument label?
Let’s answer those question, one by one…
- How can I define an argument label? You can define an argument label simply putting the label before the parameter name
1
2
3
func greet(to person: String) {
print("Hi, \(person)")
}
In the function above the argument label is the word "to"
- What changes from the perspective of a developer that wants to call the function? If you want to call a function with an argument label you can simply do it like that:
1
greet(to: "John")
You use the function name and then you use the argument label instead of the parameter name.
What changes from the perspective of the implementation of the fuction? Once again NOTHING CHANGES!!! See the implementation of the function and you can clearly understand that the code use just the parameter name.
Why should I use a specific argument label?
You should use argument label for readability reasons, to be more expressive and to make you function calls more like a sentence-like. This kind of style is very like an Objective-C style.
We’ve seen three completely different style. A super simple C-style (omitting the prefix), a stadard style (using default parameter name) and last the Objective-C way that is more readable and expressive.
Now, write the greet function with this three different styles and also call them in a Playground. What did you noticed??? If you start to write the function’s name, the auto-complete suggest to you all the three different implementation.
This means that the greet method is overloaded. There are three different implementation of the method that has the same function name (greet) but differ for the argument label. I’ve already written about overload in the previous function’s article. If you want to know a little bit more about it, read it.
Ok, I think we’re done with Argument Labels!
But before moving on to the next topic, I want to repeat an extremely important concept: if you want to understand immediately the difference between argument labels and parameters remember to put yourself in the perspective of a caller (argument label), that uses a function, or from the perspective of a developer that implement the function (parameter).
Parameters
Now let’s talk a little bit more about parameters.
Default Parameters
One thing that we should say is that we can set a default value to the parameter. In the function below we give a default value to the person parameter “Silvio”
1
2
3
func sayHi(person: String = "Silvio") {
print("Hi, \(person)")
}
Now, we can call the function without passing the person name, using the default value.
1
sayHi() // This will print ---> "Hi, Silvio"
Or we could specify a value
1
sayHi(person: "Jack")
Try yourself and practice with this concepts…. Define a function that has a default parameter and try to call it with and without an argument.
Variadic Parameters
A variadic parameter accepts zero or more value of a specified type.
As usually, let’s do some questions and let’s try to answer them in order to understand what a Variac means…
- How I declare a variadic parameter?
- What does Variadic parameter means?
Why should I use variadic parameters???
- How I declare a variadic parameter?
You simply declare a variadic parameter by inserting three period characters ...
after the parameter’s name
In the below function, we declare a printNum function that has a variadic parameter called numbers.
1
2
3
func printNum(numbers: Int...) {
print(numbers)
}
- What does Variadic parameter means? It means that I can pass a varying number of inputs when the function is called. Let see it in action with our printNum function. This case is simple, I just pass one number to the function
1
printNum(numbers: 1) // This prints >>> [1]
In this case I want to pass 4 number separated by comma
1
printNum(numbers: 1, 4, 25, 76) // This prints >>> [1, 4, 25, 76]
- Why should I use variadic parameters???
You could use variadic parameters to get you code cleaner, there is no creation of Array, Swift handles that for you. You pass a list of elements, and Swift transform it in an array. In the previous function the numbers parameter is seen as an array of Int in the body of the function. It’s important to notice that a function can have multiple variadic parameters, but the first parameter that comes after a variadic parameter MUST HAVE an argument label.
In-Out Parameters
All the parameters declared in a function are constant by default. That means that we cannot change the value of a parameter. If we try we get a compiler error. Write a function in a Playground and try to change the parameter’s value inside the body of the function. Sometimes one error worth more than a 1.000 words… That mechanism helps us to avoid to change the parameter value by mistake. But, if you want to pass a variable to a function, and let the function change the value of that argument, you should use inout parameters. You write an inout parameter by placing the inout keyword before the parameter’s type. Let’s write a simple function that takes a String representig a day in the week and prefix it with “Today is “
1
2
3
func todayIs(day: inout String) {
day = "Today is \(day)"
}
Now let’s declare a variable named aDay
with a value of “Monday”
1
var aDay = "Monday"
It’s important to note that we could only pass variables as an argument to a
inout
param, because it’s not possible to modify a constant or a literal.
But you shouldn’t trust me! Open a Playground and test it by yourself! Ok, now print the variable before calling our function.
1
print(aDay) // Not surprisingly the console prints >>> Monday
Now let’s call our function by passing the variable prefixed with an ampersand &
. (Swift is smart enough to know that you’re passing an inout params and when you use the auto-complete, it places the & just before the variable you’re passing.)
1
todayIs(day: &aDay)
And finally print again the variable
1
print(aDay) // this time the console prints >>>> Today is Monday
{Silvio Marotta}