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 trialdanilo kim
Courses Plus Student 2,947 Pointshow can i solve Swift Closures Task 1 and 2 ?
Can someone help me with this problem?
/**
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
}
2 Answers
Martin Wildfeuer
Courses Plus Student 11,071 PointsHigher 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
5,882 PointsThat 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
Courses Plus Student 11,071 PointsHey 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
10,756 PointsExcellent explanation Martin! This really helped me understand the concept.
Ben Manson
5,882 PointsThat's great! Thanks Martin! This discussion has really clarified a lot for me.
Jared Watkins
10,756 PointsThis 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
Courses Plus Student 11,071 PointsThis might be a problem with the code check. Check out this thread and let me know if that helps!
Jared Watkins
10,756 PointsThat was it! No parenthesis on the return type -> Int not -> (Int) worked in task 1 but not task 2. Thanks, Martin!!
Ben Manson
5,882 PointsBen Manson
5,882 PointsI'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:
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.