Reputation: 2249
I made an error in my code which I thought should prevent it from compiling and running, but it didn't. So I am curious, why does this compile:
func function1() {
print("function1")
func function2() {
print("function2")
}
}
function1() // prints "function1"
Upvotes: 0
Views: 65
Reputation: 63331
Because Swift supports nested functions.
... You can also define functions inside the bodies of other functions, known as nested functions.
Nested functions are hidden from the outside world by default, but can still be called and used by their enclosing function. An enclosing function can also return one of its nested functions to allow the nested function to be used in another scope.
There are many uses for them, but one common use case is to define a public function that uses a nested function to compute a result via recursion. For example, as a result of such a design, you could add parameter checking once (in the outer function), so that you don't have to repeat the checks on every call of the recursion.
func factorial(_ i: Int) -> Int {
// This check is only done once, rather than with every recursion
print("Checking to verify that i is non-negative")
guard 0 <= i else {
fatalError("Can't compute factorial of the negative number: \(i)")
}
func factorialRecurser(_ i: Int) -> Int {
print("Computing factorial of \(i)")
switch i {
case 0, 1: return 1;
default: return i * factorialRecurser(i - 1)
}
}
return factorialRecurser(i)
}
print(factorial(10))
Results in the following output:
Checking to verify that i is non-negative
Computing factorial of 10
Computing factorial of 9
Computing factorial of 8
Computing factorial of 7
Computing factorial of 6
Computing factorial of 5
Computing factorial of 4
Computing factorial of 3
Computing factorial of 2
Computing factorial of 1
3628800
Compare this to a more naive solution:
func naiveFactorial(_ i: Int) -> Int {
// This check is needlessly repeated
print("Checking to verify that i is non-negative")
guard 0 <= i else {
fatalError("Can't compute factorial of the negative number: \(i)")
}
print("Computing factorial of \(i)")
switch i {
case 0, 1: return 1;
default: return i * naiveFactorial(i - 1)
}
}
print(naiveFactorial(10))
Results in the following output:
Checking to verify that i is non-negative
Computing factorial of 10
Checking to verify that i is non-negative
Computing factorial of 9
Checking to verify that i is non-negative
Computing factorial of 8
Checking to verify that i is non-negative
Computing factorial of 7
Checking to verify that i is non-negative
Computing factorial of 6
Checking to verify that i is non-negative
Computing factorial of 5
Checking to verify that i is non-negative
Computing factorial of 4
Checking to verify that i is non-negative
Computing factorial of 3
Checking to verify that i is non-negative
Computing factorial of 2
Checking to verify that i is non-negative
Computing factorial of 1
3628800
Look at how many times the non-negative check was redundantly performed.
Upvotes: 5