-4

Within the ViewController class, I have two mapView functions:

The first mapView function handles overlays (like lines, shapes on a map, etc.)

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer

and the second mapView function handles annotations and pins on the map

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?

Coming from a C/Python background, I do not understand how you can have two functions that are named the same, and they do not overwrite one another. What's the idea behind this process?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Adib
  • 1,282
  • 1
  • 16
  • 32

3 Answers3

5

I'm sorry, but Paulo Mattos's answer is just wrong.

Function overloading does exist in Swift; it is when two functions have the same name but different signatures, meaning different parameter/return types. Thus, this is legal:

func f(x:Int) {}
func f(x:String) {}

That's legal because Swift can tell which one you're calling based on what kind of value you supply for x. That's overloading.

But your (the OP's) question has nothing to do with that. Your question is about this situation:

func f(x:Int) {}
func f(y:Int) {}

Those are just two completely different functions. The first one is called f(x:) and the second one is called f(y:). They are as different as if I had said f and g. They have completely different names.

So, the takeaway is:

  • The parameter labels are part of the name. Functions with different names (taking the parameter labels into account) were never in doubt.

  • Functions with the same name but different parameter/return types are also legal; that is overloading, which did not arise in your question.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 1
    This explains Apple's documentation of using `greet(person:)` to name the function instead of `greet`. It's still a strange behavior. Nevertheless, I learned about Function Overloading thanks to @Paulo . But is this behavior exclusive to Swift? Because on Wikipedia (https://en.wikipedia.org/wiki/Function_overloading#Rules_in_function_overloading), using the C++ example, Paolo is in the green given how different parameter names were used (Or maybe I need to learn more about this). – Adib May 01 '17 at 00:04
  • I just tried, with some success, to introduce good @adib here to the overall concept of function overloading, something important in overall scheme of things. In doing so I did not mention the vital difference, highlighted by Matt here, that not all my examples weren't technically overloaded functions in Swift land (might be in an exotic language, one might say). Anyway, hope the issue is solved for good now. Happy hacking guys! – Paulo Mattos May 01 '17 at 00:20
1

They are not the same. The first one should be read as mapViewRendererFor(mapView, overlay). The second one is mapViewViewFor(mapView, annotation)

_ are not tricky, but make it tough to explain it to first time swifters. Consider the function

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell()

In Objective-C, it's

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Objective-C and Swift include details descriptions of the parameter in the declaration in this way. May be confusing in the beginning, but makes it so readable after you're accustomed to it. And it makes APIs easy to consume. For example, a hypothetical JAVA function(I'm pretty weak in JAVA) to add a target to a button would look like:

button.add(this,didTapButton(),touchUpInside)

Compare this to Swift Code:

button.addTarget(self, action: #selector(didTapDimensionButton), for: UIControlEvents.touchUpInside)
7to4
  • 198
  • 1
  • 8
  • After reviewing the documentation on Functions (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID158) it seems the format is still sound that the function name is mapView (or tabletView in your case). Is this method you're expressing called a function? Or would it be named something else? – Adib Apr 30 '17 at 22:20
  • I'd recommend you read the "Function Argument Labels and Parameter Names" section. – 7to4 Apr 30 '17 at 22:22
  • And to answer your question, again, it's not mapview(), but mapViewRendererFor(a,b). It's not even that the 2 mapView functions are overloaded functions – 7to4 Apr 30 '17 at 22:25
0

This is often called function overloading in programming language theory. In Swift, among other languages, a function is uniquely identified by its names and arguments (i.e., types and argument labels). This function identification is sometimes called function signature. Note that the function return type isn't part of said signature.

For instance, all Swift functions below are completely different from each other:

func run()
func run(x: Int)
func run(y: Int)
func run(_ x: Int)
func run(_ y: Float)
func run(x: Int, y: Int)

As such, the run function is overloaded with many variants, hence the feature name.

But these two are the same and will trigger a compiler error:

func run(_ x: Int)
func run(_ y: Int)

both functions share the same signature since: no arg label is provided for their only arg (the _ does this trick) and the sole arg has the same type (Int).


This capability is also available in C++, C#, and Java. But in these languages, the arg name is not part of the function signature, only the arg types are. As you might guess, this is recurring source of confusion for those coming to Swift.

Conversely, the C and Python languages you mentioned, don't support overloading, which might explain your minor confusion :)

Finally, the classic Ada programming language supports a function overloading mechanism very similar to Swift.

Community
  • 1
  • 1
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
  • This explains A LOT! If I understood this correctly, if there is function overloading, the system then identifies which of the said functions satisfies the arguments provided. In the example you gave though, `func run(x: Int)` and `func run(y: Int)` would the same technically? Unless the argument name is required (which will make it easier for the computer to identify which one it should utilize). – Adib Apr 30 '17 at 22:37
  • 1
    Since Swift 3, the argument label is **required** by default. As such, the functions `run(x: Int)` and `run(y: Int)` are *not* the same indeed — the supplied arg name, by the caller, will help select the correct one. – Paulo Mattos Apr 30 '17 at 22:47
  • 1
    @adib I improved my answer a bit. Please let me know if it's better now... – Paulo Mattos Apr 30 '17 at 22:58
  • 1
    Looks good! I experimented with func run(_ *) as well to see what will happen. Thank you again for the explanation! – Adib Apr 30 '17 at 23:00
  • "This is called function overloading" No it isn't. There is no overloading here. They are _different functions entirely_. Overloading is when functions have the same name but different signatures (return types or parameters types or both). These functions have totally different names. – matt Apr 30 '17 at 23:49
  • 1
    @matt Sorry, but this is actually called [function overloading](https://en.m.wikibooks.org/wiki/Computer_Programming/Function_overloading) in programming language theory, not always an exact science one may add :) For instance, Ada supported this Swift style of overloading ages ago. Having said that, I agree with you on Swift specifically. Given its Objective-C inheritance it's merging the function name with (external) arg names, creating a totally different entity — one that is unique on its own, no overloading required, hence the confusion ;-) – Paulo Mattos May 01 '17 at 00:47