When are argument labels required in Swift? - swift

In answering this question it came about that argument labels were required for a call to init. This is normal in Swift.
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(42, "Hello world") // Missing argument labels 'one:two:' in call
However, stranger forces are at play:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run(one: "Goodbye", two: []) // Extraneous argument label 'one:' in call
To use an argument label here it would have to be declared explicitly.
I haven't seen something very thorough explaining all of this in the documentation. For which varieties of class/instance/global functions are argument labels required? Are Obj-C methods always exported and imported with argument labels?

All init methods require parameter names:
var view = NSView(frame: NSRect(x: 10, y: 10, width: 50, height: 50))
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(one: 42, two: "Hello world")
All methods called on an object use parameter names for everything but the first parameter:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run("Goodbye", two: [])
All including class functions in Swift and objective-c follow the same pattern. You also can explicitly add external names.
extension Foo{
class func baz(one: Int, two: String){}
class func other(exOne one: Int, exTwo two: String){}
}
Foo.baz(10, two:"str")
Foo.other(exOne: 20, exTwo:"str")
Swift functions that are not a class function don't require parameter names, but you still can explicitly add them:
func bar(one: Int, two: String){}
bar(1, "hello")
As Bryan said, it's to make Swift method calls make sense when called on objective-c methods that have parameter names in the method signature. Init methods include the first parameter because Swift changes the init methods from objective-c from initWith:... to Class() so the first parameter name is no longer included in the method name.

As of Swift 3.0 this has changed again: all methods, functions, and initializers require argument labels for all parameters, unless you have explicitly opted out using the external name _. This means methods such as addChildViewController(_:) are now written like this:
func addChildViewController(_ childController: UIViewController)
This was proposed and approved as part of the Swift Evolution process, and was implemented in SR-961.

Swift 3.0
In Swift 3.0, slated to be released in late 2016, the default behavior is simple:
All parameters to all methods have external labels by default.
You can find these rules most concisely in the Swift API Design Guidelines. This newest behavior was proposed in SE-0056, "establish consistent label behavior across all parameters including first labels," and implemented in SR-961. The default behavior may be changed as described below, in "Overriding the Default Behavior."
Swift 2.2
In Swift 2.2, the language's defaults for the presence of external argument labels have changed and are now simpler. The default behavior can be summarized as follows:
First parameters to methods and functions should not have external argument labels.
Other parameters to methods and functions should have external argument labels.
All parameters to initializers should have external argument labels.
The default behavior may be changed as described below, in "Overriding the Default Behavior."
An Example
These rules are best demonstrated with an example:
func printAnimal(animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
struct Player {
let name: String
let lives: Int
init(name: String, lives: Int) {
self.name = name
self.lives = lives
}
func printCurrentScore(currentScore: Int, highScore: Int) {
print("\(name)'s score is \(currentScore). Their high score is \(highScore)")
}
}
// SWIFT 3.0
// In Swift 3.0, all argument labels must be included
printAnimal(animal: "Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(currentScore: 50, highScore: 110)
// SWIFT 2.2
// In Swift 2.2, argument labels must be included or omitted in exactly the following way
// given the definition of the various objects.
printAnimal("Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(50, highScore: 110)
// In Swift 2.2, none of the following will work
printAnimal(animal: "Dog", legCount: 4) // Extraneous argument label 'animal:' in call
let q = Player("Riley", lives: 3) // Missing argument label 'name:' in call
p.printCurrentScore(50, 110) // Missing argument label 'highScore:' in call
Overriding the Default Behavior
For any parameter to any method or function, you may deviate from the language's default, though the style guide rightly warns you not to do so unless there's a good reason.
To add an external parameter label where there would normally not be one – only applicable in Swift 2.2, since Swift 3.0 defaults to assigning external labels to every parameter – or to change an external parameter label – applicable to both versions – write the desired external parameter label before the local parameter label:
func printAnimal(theAnimal animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
printAnimal(theAnimal: "Dog", legCount: 4)
To remove an external parameter label where there normally would be one, use the special external parameter label _:
func printAnimal(animal: String, _ legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
// SWIFT 3.0
printAnimal(theAnimal: "Dog", 4)
// SWIFT 2.2
printAnimal("Dog", 4)
These "default overrides" will work for any method or function, including initializers.

Here's what I've been able to gather through reading the (fairly sparse) documentation, and through plain experimentation:
Init methods always need their labels. Init methods like labels, as they make it clear what init method, exactly, you want to call. Otherwise, this:
FooBar(foos: 5)
And this:
FooBar(bars: 5)
Would look exactly the same:
FooBar(5)
Nowhere else is this the case - init methods are the only place in Swift where they all have the same name, but potentially different arguments. Which is why...
Functions, methods, etc (anything that isn't an init method) have the first label omitted - this is for style and to cut down on boring repetitiveness. Instead of
aDictionary.removeValueForKey(key: "four")
We have this:
aDictionary.removeValueForKey("four")
And still have fairly un-ambiguous and easy-to-read arguments to functions with two parameters. So instead of
anArray.insert("zebras", 9)
We have a much more understandable-on-reading form:
anArray.insert("zebras", atIndex: 9)
Which looks much better. When I was at WWDC, this was touted as a feature of Swift: Java-style modern, short arguments, without sacrificing readability. This also eases the transition from Objective-C, as Bryan Chen's answer shows.

You can make a parameter label required for calling a method using # before the label.
E.g.:
func addLocation(latitude : Double, longitude : Double) { /*...*/ }
addLocation(125.0, -34.1) // Not clear
Can be improved like so:
func addLocation(#latitude : Double, #longitude : Double) { /*...*/ }
addLocation(latitude: 125.0, longitude: -34.1) // Better
(From WWDC 2014 - 416 - Building Modern Frameworks, 15 mins in)

It is only make ObjC methods looks nice in Swift.
Documentation
Instance Methods
Local and External Parameter Names for Methods
Specifically, 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.
This convention matches the typical naming and calling convention you
will be familiar with from writing Objective-C methods, and makes for
expressive method calls without the need to qualify your parameter
names.
...
The default behavior described above mean that method definitions in Swift are written with the same grammatical style as Objective-C, and are called in a natural, expressive way.
Customizing Initialization
Local and External Parameter Names
However, initializers do not have an identifying function name before their parentheses in the way that functions and methods do. Therefore, the names and types of an initializer’s parameters play a particularly important role in identifying which initializer should be called. Because of this, Swift provides an automatic external name for every parameter in an initializer if you don’t provide an external name yourself.
For example for this ObjC class
#interface Counter : NSObject
#property int count;
- (void)incrementBy:(int)amount numberOfTimes:(int)numberOfTimes;
#end
and it written in Swift
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes: Int) {
count += amount * numberOfTimes
}
}
to call ObjC version
[counter incrementBy:10 numberOfTimes:2];
and Swift version
counter.incrementBy(10, numberOfTimes:2)
you can see they are almost the same

Related

Is there shorthand to specify a specific overload when passing a function as a closure-based argument?

I'm wondering if Swift has a way to let you pass in a specific overload of a function as an argument to a second function that takes a closure with a matching signature, based on type, but without explicitly creating a closure yourself.
Note: This is not a problem I'm trying to solve. It's just a curiosity about the language based on something I ran into when creating an extension to a struct that suddenly broke the compile. It was easily addressed with a closure, like below. It just had me wondering if there was another way to solve it.
Here's code showing what I mean. Let's start with this struct Foo...
struct Foo {
let value: Int
}
Once defined, we can use it as part of a mapping operation via a closure, like so...
let values = [1, 2, 3, 4]
let foos = values.map{ Foo(value: $0) }
However, since the initializer itself already matches the signature of the closure argument type-wise, you can skip the manually-created closure entirely and pass in the function directly, like so...
let values = [1, 2, 3, 4]
let foos = values.map(Foo.init)
What's interesting to note is Swift's compiler finds that match based only on the type of the argument to init, not it's label, which was required earlier in the closure version.
What I discovered is by defining the following extension somewhere in code-scope view of the values.map(Foo.init) call site...
extension Foo {
init(valueToDouble value: Int) { self.value = value * 2 }
}
...that call site suddenly gets flagged as ambiguous and it breaks the compile. This is because even though the labels are different, the argument type--Int in this example--is the same and it doesn't know which one to use.
Now again, this is easily solved with a simple closure, like so...
// Original init
let foos = values.map{ Foo(value: $0) }
// or init in the extension
let foos = values.map{ Foo(valueToDouble: $0) }
I'm just wondering if the Swift compiler has some 'magic sauce' that lets me do something like this...
let foos = values.map(Foo.init(valueToDouble:))
...which obviously doesn't work. :)
So is there anything like that, or is the closure-based version the (only) way to go?
Update
Well, nothing "obvious" about it being wrong because what was wrong is I had a typo (now fixed) and the above syntax does in fact work! Thanks, Itai! :)
In Swift, the "base name" of a method is the method name without any arguments:
Foo.init(x:y:z:) → Foo.init
Foo.bar(_:) → Foo.bar
Foo.baz(baz:) → Foo.baz
Foo.quux() → Foo.quux
When referring to a method by name (rather than calling it), Swift will allow you to refer to it by its base name, so long as the usage is not ambiguous:
struct Foo {
func f(intValue: Int) {}
}
let f = Foo().f
However, when there are multiple methods with the same base name, you can run into situations with ambiguity:
struct Foo {
func f(intValue: Int) {}
func f(stringValue: String) {}
}
let f = Foo().f // error: ambiguous use of 'f'
When this happens, you can either:
Use explicit typing to help disambiguate the methods, if possible:
let f1: (Int) -> Void = Foo().f
let f2: (String) -> Void = Foo().f
Or,
Refer to the method by its fully-qualified name (name with parameter names included):
let f1 = Foo().f(intValue:)
let f2 = Foo().f(stringValue:)
In your case, because both methods have the same type signature, you can't use approach (1) to disambiguate between the calls, and will have to resort to (2).
The issue you ran into is that the parameter name you were using was slightly off:
// ❌ Foo.init(doubleValue:)
// ✅ Foo.init(valueToDouble:)
let foos = values.map(Foo.init(valueToDouble:)) // ✅
This does work, and will work as a shorthand instead of having to call the method directly inside of a closure argument.

What is the difference between passing classes as generic types or types?

In the Swift documentation, I came across a section which was saying that I can write type constraints like a method or a protocol. However, what I didn't understand were the benefits of writing this way. Why don't simply pass the class (or protocol) itself?
Documentation: https://docs.swift.org/swift-book/LanguageGuide/Generics.html
Let me explain with an example.
import Foundation
class A {
init(val: String) {
self.val = val
}
let val: String
}
func someFunction<T: A>(someT: T) {
print(someT.val)
}
func someFunction2(someT: A) {
print(someT.val)
}
// method 1
someFunction(someT: A(val: "asdasd"))
// method 2
someFunction2(someT: A(val: "asdasd"))
In the snippet below, what is the difference between method 1 and method 2?
In your overly simplified example, there's not much difference.
However, as soon as your type constraints become more complex, the only way to achieve the desired interface is via generics.
A great example if when you want a function to take an input argument whose type is a protocol with an associated type, such as SwiftUI's View.
If you tried to use View as the input argument type, you'd get a compile time error
func modifyView(_ view: View) {
}
Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements
However, as soon as you make view generic with a type constraint on View, the code compiles.
func modifyView<V: View>(_ view: V) {
}
You don't have to look at custom functions, the standard library is full of generic functions as well. JSONDecoder.decode showcases another common use case for generics, when you want your function to return a specific type based on some input arguments. This enables the developer to only write the function 1x, but make it work on lots of different types, while keeping type safety.
func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T

Instantiating a nested class using NSClassFromString in swift

I have a nested class defined like this:
#objc class A {
#objc class B{
}
}
and I need to instantiate A.B using NSClassFromString. I was able to do it for the simple class A but when I attach to the NSClassFromString parameter the .B string it just returns nil.
NSClassFromString("\(appName).A") // works...
NSClassFromString("\(appName).A.B") //doesn't work.
I suppose that since nested class are not available in Objective-c the NSClassFromString just doesn't work for nested classes... in that case is there another way to initialize a nested class from a string?
// EDIT
is curious how the inverse function NSStringFromClassreturns different format when executed for a standard class and a nested class:
"myApp.A" <---- STANDARD CLASS (A)
"_TtCC15myApp13A6B" <----- NESTED CLASS (A.B)
As you can see the format is completely different. What is that _TtCC15? Why the "." has been removed? I suppose that passing the class in that format to NSClassFromString should work.
I find that the following works in a playground (Xcode 8.2 / Swift 3):
// inheriting NSObject is required for `#objc`, at which point `#objc` is optional
class A: NSObject {
class B: NSObject {
override var description: String { return "foo" }
}
}
let str = NSStringFromClass(A.B.self)
guard let anyClass = NSClassFromString(str)
else { fatalError("no class") }
// cast to a type that defines `init()` so we can instantiate
guard let nsClass = anyClass as? NSObject.Type
else { fatalError("class isn't NSObject") }
// call `.init()`, not `nsClass()`; constructor syntax is for static types only
let instance = nsClass.init()
print(instance) // -> "foo"
The oddball class "name" string is because the ObjC runtime doesn't understand nested classes (or other kinds of types that Swift can define but ObjC can't) -- within Swift itself, such mangled names are how types, functions and such get uniquely defined. (For example, name mangling is also how function overloading works: func foo() and func foo(num: Int) -> Bool have different mangled names internally.)
The bridging machinery can still be made to dynamically resolve a class given its properly mangled Swift name, but Swift name mangling is an implementation detail and subject to change. (At least until Swift 4 locks down the ABI.) So it's safe to pass the result of NSStringFromClass to NSClassFromString within the same program, but not safe to (e.g.) record a mangled name once in testing, ship that mangled name as a string literal or resource in your app, and expect it to work with NSClassFromString later.
Instead, if you want your nested class (or any other Swift-defined class) to have a reliably known name for use in the ObjC runtime, give it an #objc(name) (as described in the docs):
#objc class A: NSObject {
#objc(A_B) class B: NSObject { /*...*/ }
}
guard let anyClass = NSClassFromString("A_B")
else { fatalError("no class") }
(Note this snippet won't run by itself -- the class A.B has to be referenced at least once somewhere in your process in order to be registered with the ObjC runtime. This could be as simple as putting let t = A.B.self somewhere in your app's startup code.)

why method call is not by add(9,2) but add(9,b:2) [duplicate]

In answering this question it came about that argument labels were required for a call to init. This is normal in Swift.
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(42, "Hello world") // Missing argument labels 'one:two:' in call
However, stranger forces are at play:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run(one: "Goodbye", two: []) // Extraneous argument label 'one:' in call
To use an argument label here it would have to be declared explicitly.
I haven't seen something very thorough explaining all of this in the documentation. For which varieties of class/instance/global functions are argument labels required? Are Obj-C methods always exported and imported with argument labels?
All init methods require parameter names:
var view = NSView(frame: NSRect(x: 10, y: 10, width: 50, height: 50))
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(one: 42, two: "Hello world")
All methods called on an object use parameter names for everything but the first parameter:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run("Goodbye", two: [])
All including class functions in Swift and objective-c follow the same pattern. You also can explicitly add external names.
extension Foo{
class func baz(one: Int, two: String){}
class func other(exOne one: Int, exTwo two: String){}
}
Foo.baz(10, two:"str")
Foo.other(exOne: 20, exTwo:"str")
Swift functions that are not a class function don't require parameter names, but you still can explicitly add them:
func bar(one: Int, two: String){}
bar(1, "hello")
As Bryan said, it's to make Swift method calls make sense when called on objective-c methods that have parameter names in the method signature. Init methods include the first parameter because Swift changes the init methods from objective-c from initWith:... to Class() so the first parameter name is no longer included in the method name.
As of Swift 3.0 this has changed again: all methods, functions, and initializers require argument labels for all parameters, unless you have explicitly opted out using the external name _. This means methods such as addChildViewController(_:) are now written like this:
func addChildViewController(_ childController: UIViewController)
This was proposed and approved as part of the Swift Evolution process, and was implemented in SR-961.
Swift 3.0
In Swift 3.0, slated to be released in late 2016, the default behavior is simple:
All parameters to all methods have external labels by default.
You can find these rules most concisely in the Swift API Design Guidelines. This newest behavior was proposed in SE-0056, "establish consistent label behavior across all parameters including first labels," and implemented in SR-961. The default behavior may be changed as described below, in "Overriding the Default Behavior."
Swift 2.2
In Swift 2.2, the language's defaults for the presence of external argument labels have changed and are now simpler. The default behavior can be summarized as follows:
First parameters to methods and functions should not have external argument labels.
Other parameters to methods and functions should have external argument labels.
All parameters to initializers should have external argument labels.
The default behavior may be changed as described below, in "Overriding the Default Behavior."
An Example
These rules are best demonstrated with an example:
func printAnimal(animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
struct Player {
let name: String
let lives: Int
init(name: String, lives: Int) {
self.name = name
self.lives = lives
}
func printCurrentScore(currentScore: Int, highScore: Int) {
print("\(name)'s score is \(currentScore). Their high score is \(highScore)")
}
}
// SWIFT 3.0
// In Swift 3.0, all argument labels must be included
printAnimal(animal: "Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(currentScore: 50, highScore: 110)
// SWIFT 2.2
// In Swift 2.2, argument labels must be included or omitted in exactly the following way
// given the definition of the various objects.
printAnimal("Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(50, highScore: 110)
// In Swift 2.2, none of the following will work
printAnimal(animal: "Dog", legCount: 4) // Extraneous argument label 'animal:' in call
let q = Player("Riley", lives: 3) // Missing argument label 'name:' in call
p.printCurrentScore(50, 110) // Missing argument label 'highScore:' in call
Overriding the Default Behavior
For any parameter to any method or function, you may deviate from the language's default, though the style guide rightly warns you not to do so unless there's a good reason.
To add an external parameter label where there would normally not be one – only applicable in Swift 2.2, since Swift 3.0 defaults to assigning external labels to every parameter – or to change an external parameter label – applicable to both versions – write the desired external parameter label before the local parameter label:
func printAnimal(theAnimal animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
printAnimal(theAnimal: "Dog", legCount: 4)
To remove an external parameter label where there normally would be one, use the special external parameter label _:
func printAnimal(animal: String, _ legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
// SWIFT 3.0
printAnimal(theAnimal: "Dog", 4)
// SWIFT 2.2
printAnimal("Dog", 4)
These "default overrides" will work for any method or function, including initializers.
Here's what I've been able to gather through reading the (fairly sparse) documentation, and through plain experimentation:
Init methods always need their labels. Init methods like labels, as they make it clear what init method, exactly, you want to call. Otherwise, this:
FooBar(foos: 5)
And this:
FooBar(bars: 5)
Would look exactly the same:
FooBar(5)
Nowhere else is this the case - init methods are the only place in Swift where they all have the same name, but potentially different arguments. Which is why...
Functions, methods, etc (anything that isn't an init method) have the first label omitted - this is for style and to cut down on boring repetitiveness. Instead of
aDictionary.removeValueForKey(key: "four")
We have this:
aDictionary.removeValueForKey("four")
And still have fairly un-ambiguous and easy-to-read arguments to functions with two parameters. So instead of
anArray.insert("zebras", 9)
We have a much more understandable-on-reading form:
anArray.insert("zebras", atIndex: 9)
Which looks much better. When I was at WWDC, this was touted as a feature of Swift: Java-style modern, short arguments, without sacrificing readability. This also eases the transition from Objective-C, as Bryan Chen's answer shows.
You can make a parameter label required for calling a method using # before the label.
E.g.:
func addLocation(latitude : Double, longitude : Double) { /*...*/ }
addLocation(125.0, -34.1) // Not clear
Can be improved like so:
func addLocation(#latitude : Double, #longitude : Double) { /*...*/ }
addLocation(latitude: 125.0, longitude: -34.1) // Better
(From WWDC 2014 - 416 - Building Modern Frameworks, 15 mins in)
It is only make ObjC methods looks nice in Swift.
Documentation
Instance Methods
Local and External Parameter Names for Methods
Specifically, 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.
This convention matches the typical naming and calling convention you
will be familiar with from writing Objective-C methods, and makes for
expressive method calls without the need to qualify your parameter
names.
...
The default behavior described above mean that method definitions in Swift are written with the same grammatical style as Objective-C, and are called in a natural, expressive way.
Customizing Initialization
Local and External Parameter Names
However, initializers do not have an identifying function name before their parentheses in the way that functions and methods do. Therefore, the names and types of an initializer’s parameters play a particularly important role in identifying which initializer should be called. Because of this, Swift provides an automatic external name for every parameter in an initializer if you don’t provide an external name yourself.
For example for this ObjC class
#interface Counter : NSObject
#property int count;
- (void)incrementBy:(int)amount numberOfTimes:(int)numberOfTimes;
#end
and it written in Swift
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes: Int) {
count += amount * numberOfTimes
}
}
to call ObjC version
[counter incrementBy:10 numberOfTimes:2];
and Swift version
counter.incrementBy(10, numberOfTimes:2)
you can see they are almost the same

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).