I have this Function in a class:
func multiply(factor1:Int, factor2:Int) -> Int{
return factor1 * factor2
}
I try to call the function using this:
var multResult = calculator.multiply(9834, 2321)
The problem is that the compiler wants it to look more like this:
var multResult = calculator.multiply(9834, factor2: 2321)
Why does the first one cause an error?
The parameter names in the function call are called keyword names, and they are trace their roots back to the Smalltalk language.
Classes and objects are often re-used from somewhere else, or form part of very large complex systems, and will not have active maintenance attention for long periods at a time.
Improving the clarity and legibility of the code is very important in these situations, as code often ends up as the only documentation, when developers are under deadline pressure.
Giving each parameter a descriptive keyword name allows maintainers to quickly see what the purpose of a function call by glancing at the function call, as opposed to delving deeper into the function code itself. It makes the implied meaning of the parameters explicit.
The latest language to adopt keyword names for parameters in function calls is Rust (link) - described as "a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety."
High uptime systems require greater code quality. Keyword names allow development and maintenance teams much more opportunity to avoid and to catch errors from sending the wrong parameter, or calling parameters out of order.
They can be wordy or terse, but Smalltalkers prefer wordy and descriptive to terse and meaningless. They can afford to be, because their IDE will do the bulk of such typing for them.
The reason is historical. This is how it worked in Smalltalk and it survived into its descendants. Squeak, Scratch, Blockly, Objective C and Swift.
The kiddy languages (Squeak, Scratch and Blockly) held to it, because beginning programmers tend to struggle with the arity and parameter order. That was the original reason why Smalltalk did it that way. I do not know why ObjC and Swift decided to adopt the convention, but they did.
Because your "multiply" function is a method, and like Objective-c, the parameters in methods are part of the name.
For example you can do this.
Here there are two different methods, with different names, multiply(factor2) and multiply(factor2 factor3).
This rule only apply to methods, if you declare this like a functions outside of a class, then the function call don't require parameter name.
A note about passing in a method as an argument that returns no value:
since you used
calculator.multiply()
in the example code I'm assuming this function is a method of thecalculator
object.Swift inherits a lot of things from objective-c and this is one of them:
When in objective-c you would do (hypothetically):
the equivalent in Swift is:
Update for Swift 2.0: Now functions behave identically to methods, and for both, by default:
Other than that, the rules below still apply, except that the
#
shorthand syntax is now gone.Here's a more general answer: functions behave differently when defined as true functions outside a class, and when defined as methods. Moreover, init methods have a special rule.
Functions
Suppose you define this:
Parameter names are here only local to the function, and cannot be used when calling the function:
If you want to force using named parameters when calling the function, you can. Prefix each parameter declaration with its external name. Here, the external name of
f1
isf1param
, and forf2
, we use the shorthand where we prefix it by#
to indicate that the local name is to be used as the external name as well:Then, named parameters must be used:
Methods
Things are different for methods. By default, all but the first parameter are named, as you've discovered. Suppose we have this, and consider the
multiply1
method:Then, you have to use the name of the second (and following, if any) parameters:
You can force to use a named param for the first argument by providing an external name for it, like for functions (or prefixing its local name with
#
if you want to use the same external name as its local name). Then, you have to use it:Finally, you can declare an external name of
_
for the other following arguments, indicating that you want to call your method without using named parameters, like this:Interoperability note: If you prefix
class Calc
with the@objc
annotation, then you can use it from Objective-C code, and it is equivalent to this declaration (look at parameter names):Init Methods
The rule differs a bit for
init
methods, where all parameters have an external name by default. For instance, this works:Here, you have to specify
start:
for the overload that accepts anInt
, but you must omit it for the overload that accepts aString
.Interoperability note: this class would get exported to Objective-C like this:
Closures
Assume you define a closure type like this:
The parameter names will behave very similar to those in a method. You will have to provide the names to the parameters when calling the closure unless you explicitly set the external name to _.
For example, executing the closure:
As a rule of thumb: even if you dislike them, you should probably try to keep using named parameters at least whenever two parameters have the same type, in order to disambiguate them. I'd also argue that it's good to also name at least all
Int
andBoolean
parameters.