Resolving “Variable used within its own initial value” Error in Swift

While experimenting with a few things today, I experienced this compiler error:

Variable used within its own initial value

Let me describe the situation I was in…

I was playing (in a playground, no less) with closures, trying to mimic some behavior that I’ve recently learned about in Scala.  Essentially, I was trying to implement a factorial function as a closure, and I was trying to do it recursively (that is, without using a for/while loop).  Here’s what I wanted to do:

1let factorial = {
2    (n: Int) -> Int in
3    if (n == 0) {
4        return 1
5    } else {
6        return n * factorial(n - 1)
7    }
8}

If you’ve seen factorial before, the above implementation isn’t new.  The “base case” that will let the recursion stop is the expression if (n == 0), and the recursive case is in the else block, where factorial gets called again within its own body’s definition.  Only problem is… this doesn’t work in Swift 1.0.

Apparently, the closure (which is being initialized and assigned to the constant named “factorial”) hasn’t had a chance to fully initialize itself before the name factorial is used within the body.

The frustrating part is that I really didn’t want to type the letters v-a-r to implement my solution.  But alas, as Stack Overflow says, the following solution to the “initial value” error works:

 1var factorial: (Int) -> Int
 2factorial = {
 3    (n: Int) -> Int in
 4    if (n == 0) {
 5        return 1
 6    } else {
 7        return n * factorial(n - 1)
 8    }
 9}
10
11factorial(5)
12// Produces the correct result of 120

Of course, there’s absolutely no reason for the implementation to be a closure – I was simply experimenting.  Here’s the solution that I actually prefer… a good ole named function definition:

 1func factorial(n: Int) -> Int {
 2    if (n == 0) {
 3        return 1
 4    } else {
 5        return n * factorial(n - 1)
 6    }
 7}
 8
 9factorial(5)
10// Produces the correct result of 120

 

comments powered by Disqus