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
14
votes
1 answer

Scala: Tree Insert Tail Recursion With Complex Structure

I'm creating a tree of custom objects in scala and my insert method throws a stack overflow because it's not tail recursive. However, I can't quite figure out how to make it tail recursive. Related examples I've seen use "accumulator" variables, but…
The.Anti.9
  • 43,474
  • 48
  • 123
  • 161
14
votes
6 answers

Prolog performance and recursion type

I was playing with permutation in a couple of programs and stumbled upon this little experiment: Permutation method 1: permute([], []). permute([X|Rest], L) :- permute(Rest, L1), select(X, L, L1). Permutation method 2: permute([],…
lurker
  • 56,987
  • 9
  • 69
  • 103
14
votes
1 answer

tail call optimization in lua

Lua claims that it implement tail call properly thus no stack needs to be maintained for each call thus allow infinite recursion, I tried to write a sum function, one is not tail call, and one is tail call: non tailcall version function sum(n) …
Baiyan Huang
  • 6,463
  • 8
  • 45
  • 72
14
votes
2 answers

Tail-recursive bounded stream of pairs of integers (Scala)?

I'm very new to Scala, so forgive my ignorance! I'm trying to iterate of pairs of integers that are bounded by a maximum. For example, if the maximum is 5, then the iteration should return: (0, 0), (0, 1), ..., (0, 5), (1, 0), ..., (5, 5) I've…
Asim Ihsan
  • 1,501
  • 8
  • 18
13
votes
2 answers

Recursion over a list of s-expressions in Clojure

To set some context, I'm in the process of learning Clojure, and Lisp development more generally. On my path to Lisp, I'm currently working through the "Little" series in an effort to solidify a foundation in functional programming and…
13
votes
1 answer

How to reason about stack safety in Scala Cats / fs2?

Here is a piece of code from the documentation for fs2. The function go is recursive. The question is how do we know if it is stack safe and how to reason if any function is stack safe? import fs2._ // import fs2._ def tk[F[_],O](n: Long):…
Lev Denisov
  • 2,011
  • 16
  • 26
13
votes
2 answers

Is it recommended to use recursive IO actions in the tail recursive form?

Consider the two following variations: myReadListTailRecursive :: IO [String] myReadListTailRecursive = go [] where go :: [String] -> IO [String] go l = do { inp <- getLine; if (inp == "") then …
13
votes
3 answers

Kotlin: Tail recursion for mutually recursive functions

Suppose I write code like this: tailrec fun odd(n: Int): Boolean = if (n == 0) false else even(n - 1) tailrec fun even(n: Int): Boolean = if (n == 0) true else odd(n - 1) fun main(args:Array) { // :(…
denine99
  • 345
  • 1
  • 7
13
votes
1 answer

Memory leak in F# async recursive call

I'm confused why this function shows memory constantly increasing let rec startRead1() = async { do! Async.Sleep 1 System.GC.Collect() let mem = System.GC.GetTotalMemory(true) printfn "%d" mem do! startRead1() …
lobsterism
  • 3,469
  • 2
  • 22
  • 36
13
votes
1 answer

C# compilation with tail recursive optimization?

Based on the rich wealth of stackoverflow, I've been getting on and off answers on whether the tail recursive optimization is done to specifically c# code. A few of the questions appeared to talk about Speculation of the optimization in newer…
Bennett Yeo
  • 819
  • 2
  • 14
  • 28
13
votes
1 answer

why do continuations avoid stackoverflow?

I've been trying to understand continuations / CPS and from what I can gather it builds up a delayed computation, once we get to the end of the list we invoke the final computation. What I don't understand is why CPS prevents stackoverflow when it…
dusio
  • 480
  • 5
  • 18
13
votes
5 answers

Should I avoid tail recursion in Prolog and in general?

I'm working through "Learn Prolog now" online book for fun. I'm trying to write a predicate that goes through each member of a list and adds one to it, using accumulators. I have already done it easily without tail…
13
votes
2 answers

Why does the OCaml std lib have so many non-tail-recursive functions?

I have been rewriting many OCaml standard library functions to be tail-recursive lately. Given that this has entailed straight-forward CPS transformation, I am left puzzling over why the default versions are not written this way. As an example, in…
efrey
  • 399
  • 1
  • 12
12
votes
4 answers

Does Pharo provide tail-call optimisation?

The implementation of Integer>>#factorial in Pharo is: factorial "Answer the factorial of the receiver." self = 0 ifTrue: [^ 1]. self > 0 ifTrue: [^ self * (self - 1) factorial]. self error: 'Not valid for negative…
Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
12
votes
1 answer

What is the purpose of the extra ldnull and tail. in F# implementation vs C#?

The following C# function: T ResultOfFunc(Func f) { return f(); } compiles unsurprisingly to this: IL_0000: ldarg.1 IL_0001: callvirt 05 00 00 0A IL_0006: ret But the equivalent F# function: let resultOfFunc func =…
Asik
  • 21,506
  • 6
  • 72
  • 131