17

Consider this function:

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

Here I am assigning this function to another variable

var mathFunction: (Int, Int) -> Int = addTwoInts

Here addTwoInts is a value type or reference type? And why?

Hamish
  • 78,605
  • 19
  • 187
  • 280
Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
  • you can attempt to print memory addresses of both functions https://stackoverflow.com/questions/24058906/printing-a-variable-memory-address-in-swift if same then it's reference otherwise value – Shehata Gamal Nov 23 '18 at 17:07

3 Answers3

22

Closures and functions are Reference types. This is stated in the Swift language documentation: Closures

CPR
  • 753
  • 8
  • 19
20

I would say that a function type fits best with the definition of a reference type:

Reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used.

However I don't think this is a particularly useful distinction to make, IMO it would also be valid to make the argument that functions are value types (as technically speaking they consist of a pointer and a reference, both of which are copied when the function value is passed about).

The more useful distinction to make is that functions have reference semantics, meaning that it's possible to observe some kind of shared state between instances. This is not the same as being a reference type – it's possible for value types to have reference semantics, and for reference types to have value semantics.

For example here's a value type with reference semantics:

var foo = 0
struct S {
  var bar: Int {
    get { return foo }
    nonmutating set { foo = newValue }
  }
}

let s = S()
let s1 = s
s.bar += 1
print(s.bar)  // 1
print(s1.bar) // 1

Both s and s1 share global state, and this is observable by mutating it.

And here's a reference type with value semantics:

final class C {
  let foo = 0
}

let c = C()
let c1 = c
print(c.foo)  // 0
print(c1.foo) // 0

Although both c and c1 share state, this isn't directly observable because that shared state is immutable.

So, why do functions have reference semantics? Because they can contain captured variables, which is shared mutable state that can be observed.

For example:

func makeFn() -> () -> Int {
  var foo = 0
  return {
    foo += 1
    return foo
  }
}

let fn = makeFn()
let fn1 = fn
print(fn())  // 1
print(fn1()) // 2
Hamish
  • 78,605
  • 19
  • 187
  • 280
4

Closures and functions are reference types

Apple says : Whenever you assign a function or a closure to a constant or a variable, you are actually setting that constant or variable to be a reference to the function or closure.

In the example below, it is the choice of closure that incrementByTen refers to that is constant, and not the contents of the closure it.

Let's try and see with this example:

Firstly I will create a function takes Integer as argument returns a function called makeIncrementer

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    
    return incrementer
}

And now incrementByTen will take reference of the result of this function.In other words take a reference a closure

let incrementByTen = makeIncrementer(forIncrement: 10)

incrementByTen()
// returns a value of 10

So far so good.. What about if i call incrementByTen() again ? Result will be 10 or 20 ? Yes you got the point:) It will 20. Because Closures and functions are reference types as i said at the beginning.

incrementByTen()
// returns a value of 20
incrementByTen()
// returns a value of 30 with same approach as i explained.
zeytin
  • 5,545
  • 4
  • 14
  • 38