"Missing argument labels 'arg1:arg2:' in call" [duplicate] - swift

This question already has answers here:
Swift : missing argument label 'xxx' in call
(6 answers)
Closed 4 years ago.
var sum1 = 0
func calculatorMath(arg1: Int, arg2: Int) -> Int {
sum1 = arg1 + arg2
return sum1
}
calculatorMath(20,50)
//the problem is "Missing argument labels 'arg1:arg2:' in call". What do I need to do?

I agree with Martin R. If you are using Xcode, you should have gotten an auto fix error. The correct way to call the function would be:
calculatorMath(arg1: 20,arg2: 50)
When you have an error with argument labels, make sure to check that when you call the function, you are including them.
Good Luck!
Arnav

It has already been suggested that you can fix this by changing the call to:
calculatorMath(arg1: 20, arg2: 50)
you can also fix it by changing the declaration to:
func calculatorMath(_ arg1: Int, _ arg2: Int) -> Int {
Explanation: In Swift each parameter can have two names; an optional external name a caller must specify, and a local name that the body of the function uses (the callee). The optional external name is listed first. If it is omitted the local name must be used by the caller, if the external name is _ (an underscore) then the caller must not use any name.
For example you could declare your function as:
func calculatorMath(_ arg1: Int, arg2: Int) -> Int {
and then a call would require no label on the first arg and one on the second are:
calculatorMath(20, arg2: 50)
Note: The Swift book tends to vary in what it calls the two names/labels:
Function Argument Labels and Parameter Names
Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.
vs.
parameter → external-parameter-nameopt local-parameter-name type-annotation
‌ external-parameter-name → identifier
‌ local-parameter-name → identifier
Excerpts from: Apple Inc. “The Swift Programming Language (Swift 4.0.3).”

Related

What is the purpose of under score in when declaring a IBAction func? [duplicate]

This question already has answers here:
What is _: in Swift telling me?
(3 answers)
Closed 1 year ago.
Beginner question, I realise that when the Xcode declares a function for #IBAction, it declares it as below:
#IBAction func hardnessSelected(_ sender: UIButton),
which I read is,
Create a function called hardness selected which accepts a parameter
called sender which accepts the type UI button.
From my understanding so far _ is used when you want to declare a variable that you are not going to mutate e.g. in a for loop to tell swift the value of this variable doesn't matter to optimize performance.
However, in the above case there is a name for the variable "sender" as well as _ which I don't understand why.
Can someone please explain?
This place is declared for the label which means that once you call the function it won't appear to you for example:
func sum (_ number1: Int, _ number2: Int) {
print(number1 + number2)
}
once you call the function you won't need to mention number1 or number2 but you will only write the number directly :
sum(1, 2)
To be clear it's the same as using the function below:
func summation(myFirstNumber number1: Int, mySecondNumber number2: Int) {
print (number1 + number2)
}
but here instead of using _ I've used a label so when I called the function, I will use these labels :
summation(myFirstNumber: 1, mySecondNumber: 2)
So it's clear now that _ is instead of writing a label.
For more information check: Function Argument Labels and Parameter Names from here
Swift allows having an argumentLabel different than actual argument itself for better readability.
In case your function signature is like this -
func value(for key: String)
In this case, these values are argumentLabel == for & argument == key. At the call site, you have to mention the argumentLabel like following.
value(for: "myCustomKey")
In case your function signature is like this -
func valueForKey(_ key: String)
In this case you are explicitly asking compiler to allow you to omit argumentLabel while calling this function. Please note that argument == key will not be visible at call site for this like following.
valueForKey("myCustomKey")

Why may we use "internal argument labels" in type annotations of closures, when they (seemingly) can never be accessed?

Background
This is naturally legal:
let closure: (Int, Int) -> () = { print($0 + $1) }
closure(1, 2) // 3
Whereas, since the implementation of evolution proposal
SE-0111: Remove type system significance of function argument labels
in Swift 3, the following is not legal:
let closure: (a: Int, b: Int) -> () = { /* ... */ }
Error: function types may not have argument label a, use _ instead.
Which is expected, as, quoting from SE-0111:
Function types may only be defined in terms of the types of the formal
parameters and the return value.
Curiously, however (and as prompted by the error message above), this is legal:
let closure: (_ a: Int, _ b: Int) -> () = { print($0 + $1) }
closure(1, 2) // 3
However, as far as I can tell, we can't ever make use of a and b above (they shouldn't even be allowed, as they are not part of the types of the parameters?).
Question
Is there any reason for the final code snippet above to be legal? Can we make use or access the "internal argument labels" a and b (given the quote, we shouldn't ...), or is this possibly an oversight in the implementation of SE-0111?
What you're observing is the ability to define "purely cosmetic" parameter labels for closure types. This was accepted as a part of SE-0111, as stated in the rationale:
In response to community feedback, the core team is accepting the proposal with a revision to allow “purely cosmetic” parameter labels in closure types for documentation (as outlined in the alternatives section).
The syntax for these cosmetic parameter labels changed after the proposal to require an argument label of _, in order to make it explicit that the cosmetic labels aren't used at the call-site. This was detailed in an additional commentary:
The specific revision requested by the core team to SE-0111 is that
all “cosmetic” labels should be required to include an API name of _.
For example, this would not be allowed:
var op : (lhs : Int, rhs : Int) -> Int
instead, it should be spelled as:
var op : (_ lhs : Int, _ rhs : Int) -> Int
Although really, in practice, this makes the cosmetic labels fairly useless, as they don't show up at the call-site or even in auto-completion – only at the actual declaration itself. Therefore their intent to be self-documenting is somewhat lost.
The Swift team are aware of this shortcoming, and will be looking to make a purely additive change post-Swift 3 in order to rectify the situation.
Here's the sketch that they proposed (again, in the additional commentary):
First, we extend declaration names for variables, properties, and parameters to allow parameter names as part of their declaration name. For example:
var op(lhs:,rhs:) : (Int, Int) -> Int // variable or property.
x = op(lhs: 1, rhs: 2) // use of the variable or property.
// API name of parameter is “opToUse”, internal name is "op(lhs:,rhs:)”.
func foo(opToUse op(lhs:,rhs:) : (Int, Int) -> Int) {
x = op(lhs: 1, rhs: 2) // use of the parameter
}
foo(opToUse: +) // call of the function
This will restore the ability to express the idea of a closure
parameter that carries labels as part of its declaration, without
requiring parameter labels to be part of the type system (allowing,
e.g. the operator + to be passed into something that requires
parameter labels).
Second, extend the rules for function types to allow parameter API
labels if and only if they are used as the type of a declaration
that allows parameter labels, and interpret them as a sugar form for
providing those labels on the underlying declaration. This means that
the example above could be spelled as:
var op : (lhs: Int, rhs: Int) -> Int // Nice declaration syntax
x = op(lhs: 1, rhs: 2) // Same as above
// API name of parameter is “opToUse”, internal name is "op(lhs:,rhs:)”.
func foo(opToUse op : (lhs: Int, rhs: Int) -> Int) {
x = op(lhs: 1, rhs: 2) // Same as above.
}
foo(opToUse: +) // Same as above.
This proposed solution quite nicely allows the labels to be used at the call-site, allowing for self-documenting parameter labels, while not complicating the type-system with them. Additionally (in most cases) it allows for the expressive syntax of writing the labels next to the parameter types of the closure – which we were used to doing pre-Swift 3.
There have been complaints, not unreasonable, that if you remove the ability to name the parameters, you lose an important aspect of the human communication that tells a future maintainer or user of this code the purpose of these parameters. Well, that ability has been removed as far as external parameter names are concerned. But by leaving it open to sneak past the compiler by using just internal parameter names, we recover at least something of that communication.
However, we do not recover enough of that communication, because the internal parameters don't show up in code completion:
This has been criticized as a flaw in the new regime on this matter, and, in my opinion, rightly so.

What are 3 items in a Swift method parameter for?

Example:
mutating func moveByX(deltaX: Double, y deltaY: Double)
The first parameter takes a Double and saves it in that method scope as deltaX. However, what are y and deltaY?
I read this and can't find anything about it: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html
This is how Swift mimics Objective C's named parameters (pseudo naming of arguments). Its pretty easy to break down.
mutating func moveByX(deltaX: Double, y deltaY: Double)
1 2 3 4 5 6
Beginning of method name
First parameter name
First parameter type
Second part of method name
Second parameter name
Second parameter type
In this example, the method is actually called moveByX:y: The equivalent Objective C method definition would look like this.
- (void)moveByX:(Double)deltaX y:(Double)deltaY
When calling this method, the second part of the name is included alone with the rest of the arguments.
var dub = Double(0.5)
moveByX(dub, y: dub)
In your example,
y is the external parameter name,
deltaY is the local parameter name, and
Double is the type of the parameter.
If you are familiar with Objective-C, this corresponds to a method with the following declaration:
-(void)moveByX:(double)deltaX y:(double)deltaY;
Methods in swift have both an external parameter name and a local parameter name. External is defined first then external, if only one is defined swift compiler puts in the defaults.
Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default.
In the example, "y" is the external parameter used when calling the method, "deltaY" is the variable name used in the internal calculations of that function.
You can also use _ to signify that you don't want a parameter to have an external name.
# is used for shorthand when both your external and internal name are the same.
Examples
1)
func exampleFunction(externalVarName1 localVarName1: Int, externalVarName2 localVarName2: Int) {}
is called like this:
exampleFunction(externalVarName1: 0, externalVarName2: 0)
2)
func exampleFunction2(autocompleteHintName: Int, autocompleteHintName2: Int) {}
is called like this
exampleFunction2(0, 0)
3)
func exampleFunction3(#nameForBoth: Int, #nameForBoth2: Int) {}
is called like this
exampleFunction3(nameForBoth: 0, nameForBoth2: 0)
4)
func exampleFunction4(nameForBoth nameForBoth: Int, nameForBoth2 nameForBoth2: Int) {}
is the same as 3) but throws a warning that the # shorthhand can be used. called like this
exampleFunction4(nameForBoth: 0, nameForBoth2: 0)
5)
func exampleFunction5(_: Int, _: Int) {}
is called like this
exampleFunction5(0, 0)
deltaX and deltaY are the parameter names when you are writing the function. However, when you call the function it will be called as movebyX(val, y: val) where val is replaced by the Double you are passing into the function. The y in the middle is essentially to help the readability of the function when it is called and is common practice in swift to make your code as readable as possible (the person calling your function can easily tell what each parameter is without looking at the function header).

When to use the generic parameter clause

I'm new to generics in swift, and while reading some books, I came across something I don't understand. In generic functions, when is it appropriate to use the type parameter (the right after the function name)? and when is it inappropriate?
Here an example where it is not used (signature only; from standard library):
func sorted(isOrderedBefore: (T, T) -> Bool) -> Array<T>
Here's an example of where it is used (taken from a book I'm reading):
func emphasize<T>(inout array:[T], modification:(T) -> T) {
for i in 0 ..< array.count {
array[i] = modification(array[i])
}
}
I read Apple's swift language reference, section: Generic Parameters and Arguments. But it is still not clear to me. Thanks in advance for any insight.
 
In the first example, the generic parameter is coming from the type it is defined within. I believe it is declared within Array which already has the generic type T.
In the second example, the function itself is declaring the generic parameter. If I am not mistaken, this function is a global function. It is not already within a scope that defines a generic T.
It is only inappropriate to declare a new generic parameter in a function that obscures or tries to replace the one already declared in it's scope. For example, when extending an array, this would be inappropriate:
extension Array {
func myFunc<T>() {
}
}
Here we are defining a new T that is obscuring the original T that is already declared in the declaration of Array.
In all other circumstances where you want a generic type, you should be declaring it yourself.

Swift "with" keyword

What's the purpose of "with" keyword in Swift? So far I have found that the keyword can be used if you need to override an existing global function, such as toDebugString.
// without "with" you get "Ambiguous use of 'toDebugString'" error
func toDebugString<T>(with x: T) -> String
{
return ""
}
toDebugString("t")
with is not a keyword - it's just an external parameter identifier. This works as well:
func toDebugString<T>(whatever x: T) -> String
Since the toDebugString<T>(x: T) function is already defined, by using an external parameter you are creating an overload: same function name, but different parameters. In this case the parameter is the same, but identified with an external name, and in swift that makes it a method with a different signature, hence an overload.
To prove that, paste this in a playground:
func toDebugString<T>(# x: T) -> String {
return "overload"
}
toDebugString(x: "t") // Prints "overload"
toDebugString("t") // Prints "t"
The first calls your overloaded implementation, whereas the second uses the existing function
Suggested reading: Function Parameter Names