Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Swift Closures Functions as First Class Citizens Higher Order Functions

Marina Alenskaja
Marina Alenskaja
9,320 Points

Closures makes no sense! Please help me understand..

Hi everybody

I am currently on the mathOperation challenge in the closures course. But I simply cannot understand it. I get that I need to define a function called mathOperations that takes in a function - for example "myMathOp". This function should return (Int, Int) and then the "second" return type should also be Int (but the function returns a function?). Aaaaand, that's as far as my brain will go.

I don't understand this whole crazy line:

(Int, Int) -> Int, _ a: Int, _ b: Int)

(the example from https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID160)

I need some really patient explaining here please? :-)

Also - when and why do we use void?

Marina Alenskaja
Marina Alenskaja
9,320 Points

Pasan Premaratne The "pass in your code" option in the challenges doesn't work.

5 Answers

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,735 Points

Maybe it will help if I use the "machine" analogy. So let's say I have this machine, a blender. It takes some inputs: banana, juice, strawberries, it carries out a series of instructions and produces an output: smoothie. Now this might be a weird analogy, but let's imagine I build another machine: let's call it RobotCook. It takes ingredients, but it doesn't have a default task that it does with those ingredients. It has a spot where it requires you to stick in another machine. So if you stick a blender into that spot, it will make your ingredients into a smoothie. If you stick a waffle maker into that spot, it will make your ingredients into waffles.

So in this challenge, the function mathOperation is going to be like that RobotCook. It will perform some math operation on two numbers, but we don't know yet what that operation will be. It could be add, subtract, multiply, anything. When you call the function, in addition to passing in two numbers as arguments, it requires you to pass in a function as an argument. This will be the operation it performs on those two numbers. But it can't just be any kind of function. It has to be a function that takes in two integers as arguments, and returns one integer as its output. Otherwise our machine would break - it has to fit these constraints. Swift is designed so that we have to explicitly say what kind of function mathOperation will accept.

Here is my code:

func mathOperation(mathOp: (Int, Int) -> Int, _ a: Int, _ b:Int) -> (Int) {
  return mathOp(a, b)
}

The function mathOperation has three parameters:

  • one called mathOp, which is a function. This function takes two Ints and returns an Int.

  • one called a, which is an Int

  • one called b, which is an Int

I've put the _ before the a and b parameter names because then it doesn't get messy calling them by name later.

The return value of mathOperation is an Int

Inside mathOperation, it will return the result of calling mathOp with the arguments a and b.

mathOp could end up being anything we pass in. In the next step of the challenge, we pass in the function differenceBetweenNumbers, but it could have been any other operation as long as it fits the constraints that we spelled out.

Let me know if you need more explanation.

Marina Alenskaja
Marina Alenskaja
9,320 Points

Hi Brendan

Thank you so much for the explanation! I have one question: can you please explain a bit more about this part: I've put the _ before the a and b parameter names because then it doesn't get messy calling them by name later.

I don't think I understand why the _ can be added (I saw that in the docs too).

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,735 Points

When I did this challenge I had some problems with some of the differences between versions of Swift, and the differences between the challenges and Xcode. I ended doing sort of a workaround with the underscores. I'm not actually sure if this is necessary, but there is another thread about it:

https://teamtreehouse.com/community/the-higher-order-functions-assignment-is-not-recognizing-my-answer-as-correct-when-xcode-playground-does

Andy Chen
Andy Chen
9,414 Points

I love this explanation, it really helped me to understand this.

The analogy really helped me to image a somewhat real world analog as to how this could apply.

I understand now that "higher order functions" are almost like "more important" or "more complex" actions that take little less complicated actions and execute them.

It's kinda like how a microwave has a button to cook something, but also to defrost chicken or set a timer. It's all basically the same thing but a different input yields a different result.

Anyhoo, thanks!

Michael Reining
Michael Reining
10,101 Points

Hi Marina,

Yes, this can be confusing indeed!

Here is how I thought about it.

func differenceBetweenNumbers(a: Int, b:Int) -> (Int) {
    return a - b
}

// Think of a function as just another TYPE such as Int, String, etc.
// So in this case, you want a function called mathOperation() and the
// first parameter is of type (Int, Int) -> Int followed by to Ints.
// so you end up with this...

func mathOperation(mathOp: (Int, Int) -> Int, a: Int, b: Int) -> Int{
    return mathOp(a,b)
}
// Calling the function

let difference = mathOperation(differenceBetweenNumbers, a: 12, b: 6)

// NOTE: Part 2 of the challenge is a bit tricky because it does not accept
// the parameter lables which as of swift 2.1 are actually required.
// So enter the code below into the code challenge

let difference mathOperation(differenceBetweenNumbers, 12, 6)

I hope that helps. In regards to your question about void... void just means that nothing is being returned.

func returnNothing(myString: String) {
    print(myString)
}

func returnWithVoid(myString: String) -> Void {
    print(myString)
}

returnNothing("Test String")
returnWithVoid("Test String")


// Void is required for functions with closures like this
// Another way to think about it is that if you include a
// function that returns nothing, then you have to use void

func exampleClosure(completion: (result: String) -> Void) {
        completion(result: "we finished!")
}

// Call closure

exampleClosure() {
    (result: String) in
    // Now execute any code you like...
    print("got back: \(result)")
}

In the examples above, you have two functions that will print something to the console. Both return void but you don't have to write that in Swift.

Void, however, has to be used if you have a function that includes another function that returns nothing.

I hope that helps a little,

Mike

PS: Thanks to the awesome resources on Team Treehouse, I just launched my first app. :-)

Code! Learn how to program with Swift

Ken Alger
STAFF
Ken Alger
Treehouse Teacher

Marina;

Take a look at the docs on closures in Swift.

Post back if you have additional questions.

Happy coding,
Ken

Jhoan Arango
Jhoan Arango
14,575 Points

Hello Marina:

After reading the answers above, you can check my answer, from someone else's question. They were having difficulties understanding as well.

The focus on this particular challenge is that you are not doing a "closure" per say, you are working with higher order functions. Which are functions that take "other" functions as arguments. Not only that, but you are also working with function type.

Function types are a topic of its own, that once you understand that, then closures will be an easy topic for you.

I recommend reading this book, and search in it "function type".

Good luck and let me know if my answer helped you or if you need further explanation.

Marina Alenskaja
Marina Alenskaja
9,320 Points

Hi guys!

Thank you so much for your responses, they are awesome!! It definitly helps me understand. I love this community!! :-)