Programming in Swift: Functions and Types · Functions as Parameters | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/5429279-programming-in-swift-functions-and-types/lessons/7

Hi! I do not understand what is underline mean in the function declaration for example
" func someFunc (_ par1: Int) → Int{
par1+5
} "

@yevh The underscore actually simplifies the function call in this case after all:

  1. someFunc(_ par1: Int) is called as someFunc(4). You can’t tell what 4 actually is in this case based on the function call after all.
  2. someFunc(par1: Int) is called as someFunc(par1: 4). You can definitely tell without any doubt of any kind at all what 4 actually is based on the function call after all since it has an associated label this time.

Please do let me know if you actually have any questions or issues about the whole thing when you get a chance after all. Thank you!

At minute 4.16 in this video, printResult’s body has a constant that stores the value, and on a separate line returns that value. I tried doing it all in one line, i.e. return result = operate(a, b) and I get this error:

Converting non-escaping value to ‘Any’ may allow it to escape.

And why aren’t we allowed to do this sort of return? What does that error mean?

Hi! The printResult function isn’t meant to return anything, just print its value.
You could absolutely do that in one line, though. It would look like this:

func printResult(_ operate: Operate, _ a: Int, _ b: Int) {
  print(operate(a, b))
}

If you did want to return the result as well, you could do that! But in that case you’d probably want to only calculate the result one time, and you would need to specify the return type after the parameter list:

func printResult(_ operate: Operate, _ a: Int, _ b: Int) -> Int {
  let result = operate(a, b)
  print(result)
  return result
}

why would someone want to overload a method? Wouldn’t that only cause confusion for the developer themselves?

how to deal with variatic parametars

func add(_ a: Int..., b: Int) { a.reduce(0, +) + b }
add(1,3,4, b: 10)

var test = add
test(1,2,3,4) // cannot compile!!!

image

1 Like

@ys_xs This is quite a tricky question to answer correctly because of the way in which variadic function parameters behave when you assign functions to variables as first class citizens.

You get the following error when you run the above code:

Missing argument for parameter #2 in call

The compiler always evaluates function arguments from left to right in function calls, so it only sees the variadic Int... value of the first argument in the test(_:_:) function call in this case.

You can attempt to fix this by explicitly adding the second argument label to the test(_:_:) function call exactly the very same way as you would do with the add(_:b:) function call like this:

test(1,2,3, b: 4)

This version of the test(_:_:) function call removes any ambiguity from the previous test(_:_:) function call and makes everything more clear in this case.

The above line of code would normally work as expected in the first place and to begin with if the test(_:_:) function was a standalone function instead of a local copy of the add(_:b:) function.

The compiler removes by default all of the add(_:b:) function parameters labels from the test(_:_:) function signature when you assign the add(_:b:) function to the test(_:_:) function, so you can’t actually use any of them at all anymore in the test(_:_:) function call because of that.

You can still call the test(_:_:) function though if you switch the order of the add(_:b:) function parameters for the add(_:b:) function prototype as follows:

func add(_ a: Int, b: Int...) { a + b.reduce(0,+) }
add(1, b: 3,4,10)

The compiler now definitely knows that the first argument of the add(_:b:) function call is an Int value and the second argument of the add(_:b:) function call is a variadic Int... value.

The test(_:_:) function call now works without any more issues of any kind whatsoever:

test(1,2,3,4)

The compiler finally understands now that only the first argument of the test(_:_:) function call is an Int value while all of the other arguments of the test(_:_:) function call are part of the corresponding variadic Int... value for the test(_:_:) function call.

Please let me know if you have any more questions or other issues about the whole thing when you get a chance.

Thank you!

1 Like

Thx, very much

To sum up,
a parameter following a variadic parameter requires a label
when we assign a function to a variable, we lose all labels
so ,the only way to solve this is to put the variadic parameter in the last.

1 Like