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

how can i solve Swift Closures Task 1 and 2 ?

Can someone help me with this problem?

higherOrderFunctions.swift
/** 
  For this code challenge, let’s define a math operation as a function that 
  carries out some work on two integers and returns an integer as well. An 
  example is the function below, `differenceBetweenNumbers`, which takes two 
  integers and calculates the difference between the numbers. After calculating, 
  it returns the difference.
*/

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

// Enter your code below
func mathOperation()->(Int) {
  return differenceBetweenNumbers
}
Ben Manson
Ben Manson
5,882 Points

I've been picking at this for a while too, and can't sort it out! This is what I have, but it, too, is incorrect:

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

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

Anyone have any thoughts? How about you, Danilo? I can't figure out how to make our function mathOperation return the result of the function differenceBetweenNumbers. Simply inputing the same result as differenceBetweenNumbers gives me an error. I do think, though, that I've got the parameters correct, but I may be wrong... at the very least, I'm not getting any errors.

2 Answers

Martin Wildfeuer
PLUS
Martin Wildfeuer
Courses Plus Student 11,071 Points

Higher order functions are a bit tricky to understand, so I`ll try and explain this step by step. The whole point is that we can not only pass "simple" types like floats, ints, strings etc. to a function, but also functions themselves. In order to do that, we have to choose the parameter name, just like with all other types. Instead of specifying the type as with a String, for example, we have to add the signature of the function we want to pass.

How to get the signature of a function?

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

//Signature
(Int, Int) -> Int

func testTwo( a: Float, b: Int ) -> String {
}

//Signature
(Float, Int) -> String

So just as we would pass a string

func test( aString: String ) {
}

we can now pass a function

func test( aFunction: (Int, Int) -> Int ) {
}

In this assignment, it would be the following code. See how the signature matches differenceBetweenNumber

// func differenceBetweenNumbers(a: Int, b:Int) -> (Int)
func mathOperation( mathOp: (Int, Int) -> Int ) {
}

But we are not finished here. We want to also pass two numbers which difference can be calculated within the function body, using the function we passed. So we need three parameters: the function, number one and number two. And we also want to return the result as an Integer. So lets add this to our function:

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

Now we can calculate the difference:

let difference = mathOperation(differenceBetweenNumbers, 20, 11)

Hope that helps! Also, watch the videos again, it takes some time to get used to the concept of closures and higher order functions.

Ben Manson
Ben Manson
5,882 Points

That was a really helpful and thorough explanation, Martin! Thanks!

Just a question. In the part of code you wrote here...

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

...you write mathOp within the parentheses of the function. How can we describe what mathOp is doing here? It seems to do several things. For one thing (I think, as you say), it's the parameter name of whatever function we pass through the mathOperation function (right?). In addition, it allows us to define how any function passed through the function mathOperation will be manipulated (also unsure that thats a good way to describe what it's doing). Do those two things sound right to you? Are there additional things that i'm missing?

Martin Wildfeuer
Martin Wildfeuer
Courses Plus Student 11,071 Points

Hey Ben,

what you are saying sounds right to me. Passing a function to a function as a named parameter is not unlike assigning it to a constant (under the hood it does exactly that)

let differenceFunctionAssignedToConstant = differenceBetweenNumbers // No () as we are not calling but assigning 

then you can call it on the constant

let difference = differenceFunctionAssignedToConstant(5, 6)

You are basically doing the same when passing it to the function, in our example our constant is named mathOp

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

The only difference is that we tell the mathOperation what parameters the function we are assigning to mathOp expects and what it returns: mathOp: (Int, Int) -> Int

Why is that useful?

Well, now you are passing it differenceBetweenNumbers which does subtraction, but you can pass it any function that does take two integers and returns one, like multiplication etc.

As this is a simple example, there is not really a benefit over calling the functions directly, it just explains the concept of higher order functions.

Jared Watkins
Jared Watkins
10,756 Points

Excellent explanation Martin! This really helped me understand the concept.

Ben Manson
Ben Manson
5,882 Points

That's great! Thanks Martin! This discussion has really clarified a lot for me.

Jared Watkins
Jared Watkins
10,756 Points

This code works in my Playground, but the code challenge task 2 of 2 doesn't accept it as the answer.

let difference = mathOperation(differenceBetweenNumbers, 5, 1)

Anyone else having this issue?

Martin Wildfeuer
Martin Wildfeuer
Courses Plus Student 11,071 Points

This might be a problem with the code check. Check out this thread and let me know if that helps!

Jared Watkins
Jared Watkins
10,756 Points

That was it! No parenthesis on the return type -> Int not -> (Int) worked in task 1 but not task 2. Thanks, Martin!!