Functions & Closures behave exactly the same and have the exact same purpose only difference being a Syntax
● To declare a Function you have to use keyword func.
There is no keyword for declaring Closure.
● Function must have a name which is specified after keyword func
Closure can be without name or you can store Closure into Variable to give it a name
● Syntax for defining Input Parameters is different
○ Function can have named Input Parameters for when Function is being called
Closure can't have named Input Parameters for when Closure is being called
○ Parameter names are part of Function signature
Closure only defines Parameter Data Types (there are no names)
Based on the above observations you can think of Functions as special kind of Closures that can have
● name
● named Parameters
Closures were invented as an afterthought to make it easier to give Function as Input Parameter to other Function.
Usually to provide completion handler for asynchronous calls. Unfortunately once introduces into Swift Closures didn't
replace Functions probably because of backward compatibility or historical reasons.
Both Functions and Closures are Reference Data Types.
This means that when you assign Function or Closure to a Variable you are storing a reference to that Function or Closure.
This means that multiple Variables will point to the same Function or Closure acting as Aliases.
By being a Reference Data Types results in some strange behaviour (strange until you understand what is going on).
Closures don't capture state. Instead Closures keep the Scope alive.
Think of Closure as a medical instrument with tubes (references) attached to a Scope keeping that Scope alive.
Here by Scope we mean Function Instance - memory allocated to store Function Parameters and nested Functions.
When Function is called, new Function Instance is created where Function Parameters are stored.
In normal circumstances when Function returns, this Instance is removed from the memory because these Input
Parameters will not be used any more by anyone else so there is no point to continue to allocate memory for them.
But this is not the case if Function returns Function/Closure. Since Closures are Reference Data Type, Outer Function only
returns a reference to Inner function. This means that this Inner Function still needs to exist somewhere in memory
otherwise Reference will point to an empty space. And if this Inner Function references Input Parameters of Outer
Function then these too still need to be kept alive somewhere in the memory or Inner Function will not be able to use
them. This all leads to a strange behaviour that when outer Function returns, its Scope/Instance is not destroyed -
Instance of Outer Function continues to leave with all its Input Parameters and Inner Function still alive.
Every time Outer Function is called, new Function Instance is created with new memory allocated for Input Parameters
and Inner Function. You can think that behind the scenes new struct Instance is actually created where
● struct has Properties for storing Outer Function Input Parameters
● struct has Inner Function with only its Input Parameters, and this Inner Function references Outer Function Input
Parameters by referencing these struct Properties where these Parameters are actually stored