Search code examples
swiftalgorithmswift-extensions

Providing default instance arguments for (recursive) extension in Swift


I was having fun while practicing a Kata.
I wanted to implement one of the functions in my solution as an extension of Int, because I liked the idea of having pretty syntax. The function, in itself, looks like this:

func decomposed(_ n: Int) -> [Int] {
    if n > 10 {
      return n.decomposed(n / 10) + [n % 10] 
    } else {
      return [n]
    }
  }

Now, I've tried to implement it as an extension. Due to the fact that I would like to use it like 420.decomposed(), I figured that I would need the instance as the default argument. I proceeded with:

extension Int {
  func decomposed(_ n: Int = self) -> [Int] {
    if n > 10 {
      return n.decomposed(n / 10) + [n % 10] 
    } else {
      return [n]
    }
  }
}

This is the part, however, in which it gets trickier. I'm being told by the compiler that error: cannot find 'self' in scope.

Having read about the methods in the docs, I've resorted to using Int? default argument. Now, the extension is implemented as:

extension Int {
  func decomposed(_ n: Int? = nil) -> [Int] {
    var _n = n ?? self
    if _n > 10 {
      return _n.decomposed(_n / 10) + [_n % 10] 
    } else {
      return [_n]
    }
  }
}

I don't like the look of the _n, though.
I would love to use self as the default argument. Is that possible? Or are we stuck with hackity hacks until the judgement day?


Solution

  • You need to remove n as a parameter, replace every use of n in the function with self (since that's what's being operated on), and convert the function syntax to the method syntax in the recursion:

    extension Int {
        func decomposed() -> [Int] {
            if self > 10 {
                return (self / 10).decomposed() + [self % 10]
            } else {
                return [self]
            }
        }
    }