In particular if I have the following code:
func sum(n: Int, acc: Int) -> Int {
if n == 0 { return acc }
else { return sum(n - 1, acc + n) }
}
Yes, the swift compiler performs tail call optimisation in some cases:
func sum(n: Int, acc: Int) -> Int {
if n == 0 { return acc }
else { return sum(n - 1, acc: acc + 1) }
}
As a global function, this will use constant stack space on the "Fastest" optimisation level (-O
).
If it is inside a struct it will still use constant stack space. Within a class however, the compiler does not perform tco because the method might be overridden at runtime.
Clang also supports tco for Objective-C but often ARC calls release
after the recursive call, thus preventing this optimisation, see this article by Jonathon Mah for more details.
ARC also seems to prevent TCO in Swift:
func sum(n: Int, acc: Int, s: String?) -> Int {
if n == 0 { return acc }
else { return sum(n - 1, acc + 1, s) }
}
No TCO was performed in my tests.