Scala recursion depth limit

Is it possible to always structure a recursive function to eliminate the tail call? If not, what are some other strategies to limit stack size?

For example: ( Scala inspired tear or short circuit in Scala )

// Depth-first search of labyrinth, with large depth > stacklimit
def search ( labyrinth: SearchDomain,
             path: List[SolutionNode],
             goal: DesiredResult ) = {

  if ( path.head == goal ) return path

  candidates: List[SolutionNode] = labyrinth.childNodes(path)

  candidates.find { c =>
    Nil != search( labyrinth, c :: path, goal ) // potential boom!
  } match {
    case Some(c) => c :: path
    case None => Nil
  }
}

The goal is not to select this particular function, but to use it as a support for learning methods to limit the size of the stack.


UPDATE

My conclusion from this:

If the problem area is such that recursion may run into stack size limitation:

Rewrite the code as scala-compiler-version-of-tailcall-optimizable. This can be confirmed / confirmed by a new annotation (2.8) @ scala.annotation.tailrec.

If this is not possible, rewrite it to use iterative construction cycles.

, ( ) - , ///.

+3
5

, , , , -. , . , , . , , , .

+9

Laurence Gonsalves , , :

// Depth-first search of labyrinth, with large depth > stacklimit
def search ( labyrinth: SearchDomain,
             path: List[SolutionNode],
             goal: DesiredResult ) = {
  if ( path.head == goal ) return path

  candidates: List[SolutionNode] = labyrinth.childNodes(path)

  candidates.find { c =>
    Nil != search( labyrinth, c :: path, goal ) // potential boom!
  } match {
    case Some(c) => c :: path
    case None => Nil
  }
}

// Depth-first search of labyrinth
def search ( labyrinth: SearchDomain,
             path: List[SolutionNode],
             goal: DesiredResult ) = {
  def recurse( candidates: List[List[SolutionNode]],
               path: List[SolutionNode] ) = candidates match {
    case List(Nil) => Nil
    case Nil :: tail => recurse(tail, path.tail)
    case (nextCandidate :: otherCandidates) :: tail => 
      if (nextCandidate == goal)
        nextCandidate :: path
      else
        recurse(labyrinth.childNodes(nextCandidate :: path) :: otherCandidates,
                nextCandidate :: path)
  }

  if ( path.head == goal ) 
    path
  else
    recurse(labyrinth.childNodes(path), path)
}
+4

, .

.

+1

. , ? [] , .

scala , ( , ). - JVM, .

. question , .

+1
source

I think it is 31.

code:

scala> def facto (x:Int): Int = {
     | if (x == 0) 1
     | else x * facto(x-1)
     | }
facto: (x: Int)Int

scala> facto (31) res15: Int = 738197504

scala> facto (32) res16: Int = -2147483648

0
source

Source: https://habr.com/ru/post/1720583/


All Articles