Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differrence between closure and function as argument in swift

I have almost 4 years of experience with Objective C and a newbie in swift. Am trying to understand the concept of swift from the perspective of Objective C. So if I am wrong please guide me through :)

In objective c, we have blocks (chunck of code which can be executed later asynchronously) which made absolutely perfect sense. But in swift now we can pass a function as a parameter to another function, which can be executed later, and then we have closure as well.

As per Apple "functions are special cases of clauses."

As per O'Reilly "when a function is passed around as a value, it carries along its internal references to external variables. That is what makes a function a closure."

So I tried a little bit to understand the same :)

Here is my closure

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a ni

        let tempNumber : Int = 5

        let numbers = [1,2,3,4,5]
        print (numbers.map({ $0 - tempNumber}))
}

The variable tempNumber is declared even before the closure was declared, yet closure has the access to the variable. Now rather then a map, I tried using a custom class passed closure as a parameter and tried executing the same code :) Though now closure is getting executed in differrent scope, it still has the access to tempNumber.

I concluded : closures have an access to the variables and methods which are declared in the same scope as closure it self, though it gets execcuted in differrent scope.

Now rather then passing closure as paramter, tried passing function as a parameter,

class test {
    func testFunctionAsParameter(testMethod : (Int) -> Int){
        let seconds = 4.0
        let delay = seconds * Double(NSEC_PER_SEC)  // nanoseconds per seconds
        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

        dispatch_after(dispatchTime, dispatch_get_main_queue(), {
             self.callLater(testMethod)
        })
    }

    func callLater(testMethod : (Int) -> Int) -> Int {
        return testMethod(100)
    }
}

In a differrent class I created an instance of Test and used it as follow

/* in differrent class */
    override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a ni

            let tempAge : Int = 5

            func test2(val : Int) -> Int {
                return val - tempAge;
            }

            let testObj = test();
            print(testObj.testFunctionAsParameter(test2))
        }

Declared a class called test, which has a method called testFunctionAsParameter which in turn calls another method called callLater and finally this method executes the passed function :)

Now all these circus, just to ensure that passed method gets executed in differrent scope :)

When I executed the above code :) I was shocked to see that even though function passed as a parameter finally gets executed in different scope, still has the access to the variables testNumber that was declared at the same scope as the method declaration :)

I concluded : O'Reilly's statement "when a function is passed around as a value, it carries along its internal references to external variables." was bang on :)

Now my doubt is apple says functions are special cases of clauses. I thought special case must be something to do with scope :) But to my surprise code shows that both closure and function have access to variables in external scope !!!!

Other then, syntax differrence how closure is differrent from function passed as argument ??? Now there must be some differrence internally, otherwise Apple wouldn't have spent so much time in designing it :)

If not scope?? then what else is different in closure and function ?? O'Reilly states "when a function is passed around as a value, it carries along its internal references to external variables. That is what makes a function a closure." so what is it trying to point out ? that closure wont carry references to external variables ? Now they can't be wrong either, are they?

I am going mad with two conflicting statements from Apple and O'Reilly :( Please help, am I understanding something wrong ?? Please help me understand the difference.

like image 691
Sandeep Bhandari Avatar asked Dec 11 '22 17:12

Sandeep Bhandari


2 Answers

In swift there really isn't any difference between functions and closures. A closure is an anonymous function (A function with no name.) That's about it, other than the syntax differences you noted.

In Objective-C functions and blocks/closures ARE different.

like image 162
Duncan C Avatar answered Jan 05 '23 01:01

Duncan C


Based on your post, it looks like you have a pretty full understanding on the topic and you may just be getting lost in the semantics. It basically boils down to:

1. a closure is a closure
2. a function is a closure with a name

Here's a post with more details. But again, it's mostly a discussion of semantics. The "answer" is very simple.

What is the difference between functions and closures?

like image 24
scootermg Avatar answered Jan 05 '23 00:01

scootermg