Questions tagged [tail-recursion]

Tail recursion is a recursive strategy in which a function does some amount of work, then invokes itself. The "tail" refers to the fact that the recursion is at the very end of the function. Many -- especially functional -- programming language compilers can turn these types of calls into iteration, meaning tail recursion in supported languages can be used without fear of a stack overflow, regardless of the number of calls.

Tail recursion is a recursive strategy in which a function does some amount of work, then invokes itself. The "tail" refers to the fact that the recursion is at the very end of the function. Many (especially functional language) compilers can turn these types of calls into iterative calls, meaning tail recursion can be used without fear of a stack overflow, regardless of the number of calls.

1348 questions
10
votes
2 answers

Converting a function to use tail recursion -- a formal study

Has anyone written a formal paper describing a method to (automatically) convert functions to be tail recursive? I am looking for a university-level formal treatment including the limitations (types of functions that can be converted), procedures…
Ralph
  • 31,584
  • 38
  • 145
  • 282
10
votes
3 answers

Do recursive sequences leak memory?

I like to define sequences recursively as follows: let rec startFrom x = seq { yield x; yield! startFrom (x + 1) } I'm not sure if recursive sequences like this should be used in practice. The yield! appears to be tail…
Juliet
  • 80,494
  • 45
  • 196
  • 228
9
votes
1 answer

Overflow while using recur in clojure

I have a simple prime number calculator in clojure (an inefficient algorithm, but I'm just trying to understand the behavior of recur for now). The code is: (defn divisible [x,y] (= 0 (mod x y))) (defn naive-primes [primes candidates] (if (seq…
DanB
  • 3,755
  • 4
  • 22
  • 22
9
votes
2 answers

Why is this F# sequence function not tail recursive?

Disclosure: this came up in FsCheck, an F# random testing framework I maintain. I have a solution, but I do not like it. Moreover, I do not understand the problem - it was merely circumvented. A fairly standard implementation of (monadic, if we're…
Kurt Schelfthout
  • 8,880
  • 1
  • 30
  • 48
9
votes
6 answers

How can I express a factorial n! with an F# function, recursive or otherwise?

A factorial of a natural number (any number greater or equal than 0) is that number multiplied by the factorial of itself minus one, where the factorial of 0 is defined as 1. For example: 0! = 1 1! = 1 * 0! 2! = 2 * 1! 3! = 3 * 2! 4! = 4 * 3! 5! = 5…
delete
9
votes
2 answers

Stack overflow exception when using pipes in tail-recursive function

I have a naive implementation of a gameloop let gameLoop gamestate = let rec innerLoop prev gamestate = let now = getTicks() let delta = now - prev gamestate |> readInput delta |> update delta …
Xiol
  • 170
  • 10
9
votes
1 answer

Tail Recursive Tree Traversal without Loops

I want to traverse the following tree structure tail recursively without falling back on loops: const o = {x:0,c:[{x:1,c:[{x:2,c:[{x:3},{x:4,c:[{x:5}]},{x:6}]},{x:7},{x:8}]},{x:9}]}; 0 / \ 1 9 / | \ 2 7 8 / | \ 3 …
user6445533
9
votes
2 answers

Does F# do TCO (tail call optimization) with |> Option.bind

Here is my function: let rec applyAll rules expr = rules |> List.fold (fun state rule -> match state with | Some e -> match applyRule rule e with | Some newE -> Some newE | None -> Some e | None -> applyRule rule…
phil
  • 1,416
  • 2
  • 13
  • 22
9
votes
1 answer

Scala tree recursive fold method

Given the following definition for a (not binary) tree: sealed trait Tree[+A] case class Node[A](value: A, children: List[Node[A]]) extends Tree[A] object Tree {...} I have written the following fold method: def fold[A, B](t: Node[A])(f: A ⇒ B)(g:…
user2364174
  • 224
  • 1
  • 9
9
votes
3 answers

How can I implement a tail-recursive list append?

A simple append function like this (in F#): let rec app s t = match s with | [] -> t | (x::ss) -> x :: (app ss t) will crash when s becomes big, since the function is not tail recursive. I noticed that F#'s standard append function…
martingw
  • 4,153
  • 3
  • 21
  • 26
9
votes
2 answers

Clojure warning/error on tail call optimization failure

In Scala 2.8.x, a new annotation (@tailrec) has been added that gives a compile-time error if the compiler cannot perform a tail-call optimization on the annotated method. Is there some similar facility in Clojure with respect to…
Ralph
  • 31,584
  • 38
  • 145
  • 282
9
votes
2 answers

Does this function use tail recursion?

I am wondering if oCaml optimizes this code to be tail recursive and if so does F#? let rec sum xs = match xs with | [] -> 0 | x :: xs' -> x + sum xs'
user34537
9
votes
2 answers

LLVM tail call optimization

Here is my understanding of things: A function "f" is tail recursive when calling itself is its last action. Tail-recursion can be significantly optimized by forming a loop instead of calling the function again; the function's parameters are updated…
Jonathan Gallagher
  • 2,115
  • 2
  • 17
  • 31
9
votes
1 answer

Anything prevents optimizing tail-recursion?

I'm solving a knapsack problem in Haskell using Dynamic Programing. My first attempt was to build a two-dimensional table. But the memory easily gets blown up when the input is large(e.g. a 100 * 3190802 table). Knowing that any given row i only…
cfchou
  • 1,239
  • 1
  • 11
  • 25
8
votes
3 answers

Visit a tree or graph structure using tail recursion

Let's say I have a structure to visit in a recursive way. Pseudocode: visit(node n) { if (n == visited) return; //do something setVisited(n); foreach child_node in n.getChildren(){ visit(child_node); …
Heisenbug
  • 38,762
  • 28
  • 132
  • 190