What is the meaning of the '#' mark in swift language - swift

I have seen code like this:
func hello(name: String, #helloMessage: String) -> String {
return "\(helloMessage), \(name)."
}
My question is what # mark means before parameter's name? Is that meaning that the parameter has to be specified when calling a function?
Moreover can anyone show me a difference with the function without this # mark? Code examples are more than welcome.

Update (Swift 3.*...)
the default behavior of the first parameter’s signature was changed drastically. To understand how argument labels (ex. “external parameters”) and parameter names (ex. “local parameters”) work, please read the chapter “Function Argument Labels and Parameter Names” from the Apple’s Swift-book.
Some examples:
func someFunction(parameterName: Int) { parameterName }
someFunction(parameterName: 5) // argument label not specified
func someFunction(argumentLabel parameterName: Int) { parameterName }
someFunction(argumentLabel: 5) // argument label specified
func someFunction(_ parameterName: Int) { parameterName }
someFunction(5) // argument label omitted
There is no difference in this behavior between methods and functions.
Update (Swift 2.*)
The feature described below was deprecated, one need to write the parameter name twice to get the same behavior as with hash symbol before.
Update (examples)
For functions: when the function is called and purpose of some parameters is unclear, you provide external names for those parameters.
func someFunction(parameterName: Int) { parameterName }
someFunction(5) // What is the meaning of "5"?
func someFunction(externalParameterName parameterName: Int) { parameterName }
someFunction(externalParameterName: 5) // Now it's clear.
But if external and local names are the same, you just write a hash symbol before the parameter name.
func someFunction(#parameterName: Int) { parameterName }
// It's actually like:
// func someFunction(parameterName parameterName: Int) { parameterName }
someFunction(parameterName: 5)
For methods: by default first parameter name is only local (like by functions), but second and subsequent parameter names are both local and external (like as you write a hash symbol before the parameter name, this # is implicitly there):
class SomeClass {
func someMethodWith(firstParameter: Int, andSecondParameter: Int) { ... }
}
SomeClass().someMethodWith(5, andSecondParameter: 10)
You can use # (or add an explicit external name) for the first parameter of the method too, but it'll not match Objective-C-style calling.
class SomeClass {
func someMethodWith(#firstParameter: Int, andSecondParameter: Int) { ... }
}
SomeClass().someMethodWith(firstParameter: 5, andSecondParameter: 10)
Original answer
If you want to provide an external parameter name for a function
parameter, and the local parameter name is already an appropriate name
to use, you do not need to write the same name twice for that
parameter. Instead, write the name once, and prefix the name with a
hash symbol (#). This tells Swift to use that name as both the local
parameter name and the external parameter name.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/ru/book/swift-programming-language/id881256329?l=en&mt=11

This has changed in Swift 2:
now you specify an external parameter name before the internal one, instead of using # to force the existing name.
According to the convention, the method name contains the action verb and the first parameter is not specified when calling the method:
func sayHiFrom(sender: String, to: String) {
print("Hi from \(sender) to \(to)!")
}
sayHiFrom("Jules", to: "Jim")
Specifying an internal parameter name
This time the second parameter has a different name for using inside the method, without changing the external name. When there is two names for a parameter, the first one is external and the second one is internal:
func sayHiFrom(sender: String, to receiver: String) {
print("Hi from \(sender) to \(receiver)!")
}
sayHiFrom("Jane", to: "John")
Forcing an external parameter name
You can force the first parameter to have an external name:
func sayHi(from sender: String, to receiver: String) {
print("Hi from \(sender) to \(receiver)!")
}
sayHi(from: "Joe", to: "Jack")
In this case, it's better that the method name does not contain the action term, because the forced parameter name already plays its role.
Forcing no external parameter names
You can also remove the parameter name for other parameters by preceding them with _ (underscore):
func sayHi(sender: String, _ receiver: String) {
print("Hi from \(sender) to \(receiver)!")
}
sayHi("Janice", "James")

**
Shorthand External Parameter Names
**
If you want to provide an external parameter name for a function parameter, and the local parameter name is already an appropriate name to use, you do not need to write the same name twice for that parameter. Instead, write the name once, and prefix the name with a hash symbol (#). This tells Swift to use that name as both the local parameter name and the external parameter name.
This example defines a function called containsCharacter, which defines external parameter names for both of its parameters by placing a hash symbol before their local parameter names:
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}
This function’s choice of parameter names makes for a clear, readable function body, while also enabling the function to be called without ambiguity:
let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
// containsAVee equals true, because "aardvark" contains a "v”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
https://itun.es/in/jEUH0.l

With previous versions of Swift everything what #ovejka posted was true. In Swift 2.0 and above it looks like # is unused (in this or similar context, not counting #available)

I agree. It is confusing, but I hope this helps clear it up.
If you don't use #, you can enter parameters without using their names, as long as they are in order:
func x(a:Int, b:Int, c:Int) {some code}
x(10,20,30) or x(a:10, b:20, c:30) //Still have to be in order!
...but if you add #, the first variant is not allowed, i.e. x(10,20,30), as Swift now forces labels to be used. You can only use x(a:10, b:20, c:30).
Why would that be? Clarity. Makes code more readable.

Related

What is the use of the "of" keyword in Swift? [duplicate]

This question already has an answer here:
Swift "with" keyword
(1 answer)
Closed 3 years ago.
Example:
func student(of name: String) -> String {
.
.
.
}
In that context, it's merely part of a method signature. To my knowledge, of is not a word that's used in Swift. To utilize that method, you'd type:
student(of: "<Student's name here>") and it would return a string.
If you omitted of from the signature above (func student(name: String) -> String), the method would be called as follows:
student(name: "Student's name here")
Lastly, if you changed the signature to put an underscore in front of the parameter, like so func student(_ name: String) -> String, you'd call the method as follows:
student("Student's name here")
In this case, "of" is the label for the argument called "name".
If you were to call this function, it would be
student(of: "Mathematics")
However inside the student function, you would get it's value with "name"
func student(of name: String) -> String {
print(name)
// TODO: Do something and return
}
Just a suggestion, IMHO "of" is not very descriptive of what the function does or what "of" represents (is "of" an id? The name of the student?).
Swift has a concept of external as well as internal parameter name. External parameter names are used to make the function signature more readable where as Internal parameter names are used for usage inside the function.
External parameter names are optional. If only one parameter name is provided, that name is used as both External and Internal. An External parameter name for the first parameter is required. If at any stage, you don't want to specify an External parameter, you can replace it with _.
Consider the following example:
func myFunctionToPrintDetailsOfStudentWithFirstName(_ firstName: String, andLastName lastName: String, fromAddress: String)
Note that in this example, the first parameter has an Internal name only, the second parameter has both and the last one only has one. The function call would look like
myFunctionToPrintDetailsOfStudentWithFirstName("John", andLastName: "Doe", fromAddress: "My Country")
As you can see, the first parameter is passed without a parameter name, the second parameter is passed using the External name and the last parameter is passed using the only parameter name. This makes the function call more readable.
Note:
Within the function declaration, the first parameter would be accessed by firstName, the second by lastName and the last one by fromAddress
Hope this clarifies the differences for you

Are Swift 4 custom argument labels ALWAYS required or just for disambiguation of functions?

This question is similar to
Swift 4 custom argument labels - required?
but more specific. I came across that question when researching a problem caused by changing from a var (requiring no parameter) to a func (requiring a parameter) but missed changing all references. I have created a playground that contradicts the claim made in a subsequent edit to that question: "question is incorrect, as custom labels are mandatory"
My question is: how to correctly express what I observed, as demonstrated below:
class SomeTest {
static func someParam(p1: String?) -> String? {
return "hello \(p1 ?? "nothing")"
}
// Uncommenting the following causes error at let funny
// static func someParam(p2: String?) -> String? {
// return "hello \(p2 ?? "nothing")"
// }
static func doIt() {
let funny = someParam // ignoring the argument label is ok if there is no ambiguity
funny("thing") // and can be used without
someParam(p1: "thing2") // must have argument label
}
}
SomeTest.doIt()
If you have both someParam functions (each with a differently named parameter), then the line:
let funny = someParam
no longer works since it isn't known which of the two someParam functions you are referring to. This is solved by providing an unambiguous name:
let funny = someParam(p1:) // or someParam(p2:)
Note that funny has a type of (String?) -> String?. Both someParam functions have that same type. This is why you need to provide more detail to disambiguate the two. The parameter names don't change the function type.
When directly calling a function you must provide the full function name which includes any named parameter labels.
But when you create a closure variable and assign it the value of a function, you don't need to provide more than the base name of the function if that name is unambiguous in the given context.

why do we need the argument labels during the function call in swift

I have just started reading Learn Essentials of Swift
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
syntax to call
greet("Anna",day : "Tuesday")
My Questions:
What is the real need of sending the name of the parameter
Will it match the name before copying the value in the function
If it matches the names , if i interchange values while i call the function , below code fails
func greet(name: String, day: String,time: String) -> String
{
return "Hello \(name), today is \(day), \(time)."
}
greet("Anna", time: "one forty",day: "Tuesday")
How does the function parameter mechanism work internally ?
As you find in the link in the comment, there are some advantages of named parameters: They make the code clearer.
However, in Objective-C there has been named parameters from the very beginning. To be more honest, they have been akin of named parameters, because the names are part of the method name (selector). In your example, the method in Objective-C would be: greetName:day:. This is different from greetName:day:time:. At least Swift needs the capability to handle that.
What is the real need of sending the name of the parameter
Names parameters make the code more readable. There can be many methods with different parameter names.
Will it match the name before copying the value in the function
Yes. It builds the function name from the argument names in the call and try to match it with the parameter names of a potential method.
If it matches the names , if i interchange values while i call the function , below code fails
In Objective-C and Swift the order of the named parameters is important. You can have two different methods with interchanged names. greetName:day:time: is different to greetName:time:day:.

Swift 3 first parameter names

In Swift 2, it appears that the first parameter name is not always required when calling a function. Now in Swift 3, the first parameter name is required when calling the function. For example:
func frobnicate(runcible: String) {
print("Frobnicate: \(runcible)")
}
Swift 2.2 allowed the function to be called by simply typing:
Frobnicate("Station")
Swift 3 seems to be requiring that we use the first parameter names of methods such as:
Frobnicate(runcible:"Station")
Is this the case with Swift 3 for all functions and methods or just certain situations?
Yes, this is right. Swift is fixing a language inconsistency this way (this was always required for initializers).
If you don't want to use the external parameter name, just remove it explicitly:
func frobnicate(_ runcible: String) {
print("Frobnicate: \(runcible)")
}
You can read the full rationale in Swift Evolution 0046
You can read The Swift Programming Language (Swift 3) in i-Book. Also you can check this out in WWDC 2016: What's New in Swift
In Swift 3, by default, functions use their parameter names as labels for their arguments. Write a custom argument label before the parameter name, or write _ to use no argument label.
fun greet(_ person: String, on day: String) -> String {
return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")
or
// This also works with Swift 2
fun addThreeNumber(_ first: Int, _ second: Int, _ third: Int) {
print(first+second+third)
}
addThreeNumber(1, 2, 3)
Exactly. In Swift 3.0, it's mandatory to write parameter names for all the parameters (including the first parameter). Parameter name is the one which is used inside the function implementation body.
func frobnicate(runcible: String) {
print("Frobnicate: \(runcible)")
}
By default, the external parameter label is same as the parameter name, if you don't specify any parameter label explicitly. Parameter label is the one which is used to pass the arguments while calling the function. If you need, for better clarity purpose, you can also specify external parameter labels explicitly. Example below-
func frobnicate(runcibleExternalLabel runcible: String) {
print("Frobnicate: \(runcible)")
}
If you want to skip the external parameter label while calling the function, just prepend a "_" before the parameter name.
func frobnicate(_ runcible: String) {
print("Frobnicate: \(runcible)")
}
Yes Swift 3 requires you to send First Parameter Label.
Please refer Swift 3 changes
The reason you want labels for parameters is so other code can supply parameters in any order.
Without labels, when you call the function the parameters are anonymous and you cannot be certain if you have supplied them in the wrong order.
Place labels in front of the parameters and code tools can do a much better job at catching errors us humans put in.
The underscore is just a way to cope with the transition from legacy code; method names including an Implicit first parameter. You should change any underscores that migration adds to your code to an explicit parameter label. You know it makes sense.

Why is Method requiring only second parameter "argument"?

I have the following method inside a User Class:
func Login(username: String, password: String) -> String
{
return "Login Success";
}
Why on Earth it only works calling it if I specify the second parameter "label"(not sure what it is called)?
var loginReturn = user.Login("aa", password: "zz");
iIf I do the following I got error:
var loginReturn = user.Login("aa", "zz");
I'm not happy with Swift.
From Functions in Swift
Function parameters have both an external parameter name and a local parameter name. An external parameter name is used to label arguments passed to a function call. A local parameter name is used in the implementation of the function.
(...)
By default, the first parameter omits its external name, and the second and subsequent parameters use their local name as their external name.
(...)
Omitting External Parameter Names
If you do not want to use an external name for the second or subsequent parameters of a function, write an underscore (_) instead of an explicit external name for that parameter.
I recommend you to read the whole chapter, it should clear up your confusion.
Also note that the external parameter names are technically a part of the function/method name.
You can write it like this:
func Login(username: String, _ password: String) -> String
{
return "Login Success";
}
For every method parameter you can define "inner" and "outer" parameters which will define the final look of the methods call.
If you call a function that has two parameters, you must list the name of the parameters after the first one if they have a name. With the current way you've written your function...
This Code Works
var loginReturn = login("aa", password: "zz")
And This Code Fails
var loginReturn = login("aa", "zz")