Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composing Functions Leads to StackOverflow

Tags:

scala

Functional Programming in Scala lists the following example as to how composing functions can lead to a StackOverflowError.

scala> val f = (x: Int) => x
f: Int => Int = <function1>

scala> val g = List.fill(100000)(f).foldLeft(f)(_ compose _)
g: Int => Int = <function1>

scala> g(42)
java.lang.StackOverflowError

As the book explains, g is a composite function that has 100,000 functions where each one calls the next.

Since foldLeft is tail-recursive, why does this StackOverflowError occur? How, if at all, are tail-recursion and StackOverflow's related?

When (as it's expanded) the second argument (B, A) => B of foldLeft, ((acc, elem) => acc.compose(elem)), doesn't each fold step result in composing only 2 functions?

like image 584
Kevin Meredith Avatar asked Dec 12 '25 23:12

Kevin Meredith


1 Answers

Since foldLeft is tail-recursive, why does this StackOverflowError occur? How, if at all, are tail-recursion and StackOverflow's related?

When (as it's expanded) the second argument (B, A) => B of foldLeft, ((acc, elem) => acc.compose(elem)), doesn't each fold step result in composing only 2 functions?

Note that the fold itself (i.e. the line val g = ...) doesn't overflow stack. However, g ends up being defined effectively as f(f(...(x))) and therefore you need 100000 stack frames to evaluate g(42) which obviously does overflow.

like image 160
Alexey Romanov Avatar answered Dec 15 '25 23:12

Alexey Romanov