<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.sarg.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=2605%3A8D80%3A6C24%3A88A9%3AE0B2%3AAD7C%3A76A8%3A4BDF</id>
	<title>Vero - Wikipedia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.sarg.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=2605%3A8D80%3A6C24%3A88A9%3AE0B2%3AAD7C%3A76A8%3A4BDF"/>
	<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php/Special:Contributions/2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF"/>
	<updated>2026-08-14T17:36:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wiki.sarg.dev/index.php?title=Inline_expansion&amp;diff=150046</id>
		<title>Inline expansion</title>
		<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php?title=Inline_expansion&amp;diff=150046"/>
		<updated>2025-10-19T16:12:44Z</updated>

		<summary type="html">&lt;p&gt;2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF: Brackets and update code aligning it&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Short description|Optimization replacing a function call with that function&#039;s source code}}&lt;br /&gt;
{{Use American English|date=March 2019}}&lt;br /&gt;
{{More citations needed|date=December 2013}}&lt;br /&gt;
&lt;br /&gt;
In [[computing]], &#039;&#039;&#039;inline expansion&#039;&#039;&#039;, or &#039;&#039;&#039;inlining&#039;&#039;&#039;, is a manual or [[compiler optimization]] that replaces a function [[call site]] with the body of the called function. Inline expansion is similar to [[macro expansion]], but occurs during compiling, without changing the [[source code]] (the text), while macro expansion occurs before compiling, and results in different text that is then processed by the [[compiler]].&lt;br /&gt;
&lt;br /&gt;
Inlining is an important optimization, but has complex effects on performance.{{sfn|Chen|Chang|Conte|Hwu|1993}} As a [[rule of thumb]], some inlining will improve speed at very minor cost of space, but excess inlining will hurt speed, due to inlined code consuming too much of the [[instruction cache]], and also cost significant space. A survey of the modest academic literature on inlining from the 1980s and 1990s is given in Peyton Jones &amp;amp; Marlow 1999.{{sfn|Peyton Jones|Marlow|1999|loc=8. Related work, p. 17}}&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
Inline expansion is similar to macro expansion as the compiler places a new copy of the function in each place it is called. Inlined functions run a little faster than the normal functions as function-calling-overheads are saved, however, there is a memory penalty. If a function is inlined 10 times, there will be 10 copies of the function inserted into the code. Hence inlining is best for small functions that are called often. In C++ the member functions of a class, if defined within the class definition, are inlined by default (no need to use the &#039;&#039;inline&#039;&#039; [[reserved word]] (keyword)); otherwise, the keyword is needed. The compiler may ignore the programmer’s attempt to inline a function, mainly if it is particularly large.&lt;br /&gt;
&lt;br /&gt;
Inline expansion is used to eliminate the time overhead (excess time) when a function is called. It is typically used for functions that execute frequently. It also has a space benefit for very small functions, and is an enabling transformation for other [[Optimization (computer science)|optimizations]].&lt;br /&gt;
&lt;br /&gt;
Without inline functions, the [[compiler]] decides which functions to inline. The programmer has little or no control over which functions are inlined and which are not. Giving this degree of control to the programmer allows for the use of application-specific knowledge in choosing which functions to inline.&lt;br /&gt;
&lt;br /&gt;
Ordinarily, when a function is invoked, [[control flow|control]] is transferred to its definition by a [[branch (computer science)|branch]] or call instruction. With inlining, control drops through directly to the code for the function, without a branch or call instruction.&lt;br /&gt;
&lt;br /&gt;
[[Compiler]]s usually implement [[Statement (computer science)|statements]] with inlining. Loop conditions and loop bodies need [[lazy evaluation]]. This property is fulfilled when the code to compute loop conditions and loop bodies is inlined. Performance considerations are another reason to inline statements.&lt;br /&gt;
&lt;br /&gt;
In the context of [[functional programming]] languages, inline expansion is usually followed by the [[Lambda calculus#.CE.B2-reduction|beta-reduction]] transformation.&lt;br /&gt;
&lt;br /&gt;
A programmer might inline a function manually through [[copy-and-paste programming]], as a one-time operation on the [[source code]]. However, other methods of controlling inlining (see below) are preferable, because they do not precipitate bugs arising when the programmer overlooks a (possibly modified) duplicated version of the original function body, while fixing a bug in the inlined function.&lt;br /&gt;
&lt;br /&gt;
==Effect on performance==&lt;br /&gt;
The direct effect of this optimization is to improve time performance (by eliminating call overhead), at the cost of worsening space usage{{efn|Space usage is &amp;quot;number of instructions&amp;quot;, and is both runtime space usage and the [[binary file]] size.}} (due to [[code duplication|duplicating]] the function body). The code expansion due to duplicating the function body dominates, except for simple cases,{{efn|Code size actually shrinks for very short functions, where the call overhead is larger than the body of the function, or single-use functions, where no duplication occurs.}} and thus the direct effect of inline expansion is to improve time at the cost of space.&lt;br /&gt;
&lt;br /&gt;
However, the main benefit of inline expansion is to allow further optimizations and improved scheduling, due to increasing the size of the function body, as better optimization is possible on larger functions.{{sfn|Chen|Chang|Conte|Hwu|1993|loc=3.4 Function inline expansion, p. 14}} The ultimate impact of inline expansion on speed is complex, due to multiple effects on performance of the memory system (mainly [[instruction cache]]), which dominates performance on modern processors: depending on the specific program and cache, inlining particular functions can increase or decrease performance.{{sfn|Chen|Chang|Conte|Hwu|1993}}&lt;br /&gt;
&lt;br /&gt;
The impact of inlining varies by [[programming language]] and program, due to different degrees of abstraction. In lower-level imperative languages such as [[C (programming language)|C]] and [[Fortran]] it is typically a 10–20% speed boost, with minor impact on code size, while in more abstract languages it can be significantly more important, due to the number of layers inlining removes, with an extreme example being [[Self (programming language)|Self]], where one compiler saw improvement factors of 4 to 55 by inlining.{{sfn|Peyton Jones|Marlow|1999|loc=8. Related work, p. 17}}&lt;br /&gt;
&lt;br /&gt;
The direct benefits of eliminating a function call are:&lt;br /&gt;
* It eliminates instructions needed for a [[function call]], both in the calling function and in the callee: placing arguments on a [[Stack-based memory allocation|stack]] or in [[Processor register|registers]], the function call itself, the [[function prologue]], then at return the [[function epilogue]], the [[return statement]], and then getting the return value back, and removing arguments from stacks and restoring registers (if needed).&lt;br /&gt;
* Due to not needing registers to pass arguments, it reduces [[register spilling]].&lt;br /&gt;
* It eliminates having to pass references and then dereference them, when using [[call by reference]] (or [[call by address]], or [[call by sharing]]).&lt;br /&gt;
&lt;br /&gt;
The main benefit of inlining, however, is the further optimizations it allows. Optimizations that cross function boundaries can be done without requiring [[interprocedural optimization]] (IPO): once inlining has been performed, added &#039;&#039;intra&#039;&#039;procedural optimizations (&amp;quot;global optimizations&amp;quot;) become possible on the enlarged function body. For example:&lt;br /&gt;
* A [[Constant (computer programming)|constant]] passed as an argument can often be propagated to all instances of the matching parameter, or part of the function may be &amp;quot;hoisted out&amp;quot; of a loop (via [[loop-invariant code motion]]).&lt;br /&gt;
* [[Register allocation]] can be done across the larger function body.&lt;br /&gt;
* High-level optimizations, such as [[escape analysis]] and [[tail duplication]], can be performed on a larger scope and be more effective, more so if the compiler implementing those optimizations relies on mainly intra-procedural analysis.&amp;lt;ref name=&amp;quot;prokopec2019&amp;quot; /&amp;gt; These can be done without inlining, but require a significantly more complex compiler and linker (in case caller and callee are in separate compiling units).&lt;br /&gt;
&lt;br /&gt;
Conversely, in some cases a language specification may allow a program to make added assumptions about arguments to procedures that it can no longer make after the procedure is inlined, preventing some optimizations. Smarter compilers (such as [[Glasgow Haskell Compiler]] (GHC)) will track this, but naive inlining loses this information.&lt;br /&gt;
&lt;br /&gt;
A further benefit of inlining for the memory system is:&lt;br /&gt;
* Eliminating branches and keeping code that is executed close together in memory improves instruction cache performance by improving [[locality of reference]] (spatial locality and sequentiality of instructions). This is smaller than optimizations that specifically target sequentiality, but is significant.{{sfn|Chen|Chang|Conte|Hwu|1993|loc=3.4 Function inline expansion, p. 19–20}}&lt;br /&gt;
&lt;br /&gt;
The direct cost of inlining is increased code size, due to duplicating the function body at each call site. However, it does not always do so, namely in case of very short functions, where the function body is smaller than the size of a function call (at the caller, including argument and return value handling), such as trivial [[accessor method]]s or [[mutator method]]s (getters and setters); or for a function that is only used in one place, in which case it is not duplicated. Thus inlining may be minimized or eliminated if optimizing for code size, as is often the case in [[embedded system]]s.&lt;br /&gt;
&lt;br /&gt;
Inlining also imposes a cost on performance, due to the code expansion (due to duplication) hurting instruction cache performance.&amp;lt;ref name=&amp;quot;webkit&amp;quot;&amp;gt;{{cite web |url=https://www.webkit.org/blog/2826/unusual-speed-boost-size-matters/ |title=Unusual speed boost: size matters |author=Benjamin Poulain |date=August 8, 2013}}&amp;lt;/ref&amp;gt; This is most significant if, before expansion, the [[working set]] of the program (or a hot section of code) fit in one level of the memory hierarchy (e.g., [[L1 cache]]), but after expansion it no longer fits, resulting in frequent cache misses at that level. Due to the significant difference in performance at different levels of the hierarchy, this hurts performance considerably. At the highest level this can result in increased [[page fault]]s, catastrophic performance degradation due to [[thrashing (computer science)|thrashing]], or the program failing to run at all. This last is rare in common desktop and server applications, where code size is small relative to available memory, but can be an issue for resource-constrained environments such as embedded systems. One way to mitigate this problem is to split functions into a smaller hot inline path ([[fast path]]), and a larger cold non-inline path (slow path).&amp;lt;ref name=&amp;quot;webkit&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inlining hurting performance is a problem for mainly large functions that are used in many places, but the break-even point beyond which inlining reduces performance is difficult to determine and depends in general on precise load, so it can be subject to manual optimization or [[profile-guided optimization]].&amp;lt;ref&amp;gt;See for example the [http://jikesrvm.org/Adaptive+Optimization+System Adaptive Optimization System] {{Webarchive|url=https://web.archive.org/web/20110809144146/http://jikesrvm.org/Adaptive+Optimization+System |date=2011-08-09}} in the [[Jikes RVM]] for Java.&amp;lt;/ref&amp;gt; This is a similar issue to other code expanding optimizations such as [[loop unrolling]], which also reduces number of instructions processed, but can decrease performance due to poorer cache performance.&lt;br /&gt;
&lt;br /&gt;
The precise effect of inlining on cache performance is complex. For small cache sizes (much smaller than the working set before expansion), the increased sequentiality dominates, and inlining improves cache performance. For cache sizes close to the working set, where inlining expands the working set so it no longer fits in cache, this dominates and cache performance decreases. For cache sizes larger than the working set, inlining has negligible impact on cache performance. Further, changes in cache design, such as [[load forwarding]], can offset the increase in cache misses.{{sfn|Chen|Chang|Conte|Hwu|1993|loc=3.4 Function inline expansion, p. 24–26}}&lt;br /&gt;
&lt;br /&gt;
==Compiler support==&lt;br /&gt;
Compilers use a variety of mechanisms to decide which function calls should be inlined; these can include manual hints from programmers for specific functions, together with overall control via [[command-line option]]s. Inlining is done automatically by many compilers in many languages, based on judgment of whether inlining is beneficial, while in other cases it can be manually specified via compiler [[Directive (programming)|directives]], typically using a keyword or [[compiler directive]] called &amp;lt;code&amp;gt;inline&amp;lt;/code&amp;gt;. Typically this only hints that inlining is desired, rather than requiring inlining, with the force of the hint varying by language and compiler.&lt;br /&gt;
&lt;br /&gt;
Typically, compiler developers keep the above performance issues in mind, and incorporate [[heuristics]] into their compilers that choose which functions to inline so as to improve performance, rather than worsening it, in most cases.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
Once the [[compiler]] has decided to inline a particular function, performing the inlining operation itself is usually simple. Depending on whether a compiler inlines functions across code in different languages, the compiler can inline on either a high-level [[intermediate representation]] (like [[abstract syntax tree]]s) or a low-level intermediate representation. In either case, the compiler simply computes the [[Parameter|arguments]], stores them in variables corresponding to the function&#039;s arguments, and then inserts the body of the function at the call site.&lt;br /&gt;
&lt;br /&gt;
[[Linker (computing)|Linkers]] can also do function inlining. When a linker inlines functions, it may inline functions whose source is not available, such as library functions (see [[link-time optimization]]). A [[runtime system]] can inline a function also. [[Runtime (program lifecycle phase)|Runtime]] inlining can use dynamic profiling information to make better decisions about which functions to inline, as in the [[HotSpot (virtual machine)|Java HotSpot compiler]].&amp;lt;ref&amp;gt;[https://www.researchgate.net/publication/331408280_An_Optimization-Driven_Incremental_Inline_Substitution_Algorithm_for_Just-in-Time_Compilers] Description of the inliner used in the Graal JIT compiler for Java&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is a simple example of inline expansion performed &amp;quot;by hand&amp;quot; at the source level in the [[C (programming language)|C language]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int pred(int x) {&lt;br /&gt;
    if (x == 0) {&lt;br /&gt;
        return 0;&lt;br /&gt;
    } else {&lt;br /&gt;
        return x - 1;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Before inlining:&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int func(int y) {&lt;br /&gt;
    return pred(y) + pred(0) + pred(y + 1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;After inlining:&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int func(int y) {&lt;br /&gt;
    int tmp;&lt;br /&gt;
&lt;br /&gt;
    // (1)&lt;br /&gt;
    if (y == 0) {&lt;br /&gt;
        tmp  = 0; &lt;br /&gt;
    } else {&lt;br /&gt;
        tmp  = y - 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // (2)&lt;br /&gt;
    if (0 == 0) {&lt;br /&gt;
        tmp += 0;&lt;br /&gt;
    } else {&lt;br /&gt;
        tmp += 0 - 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // (3)&lt;br /&gt;
    if (y + 1 == 0) {&lt;br /&gt;
        tmp += 0;&lt;br /&gt;
    } else {&lt;br /&gt;
        tmp += (y + 1) - 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tmp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is only an example. In an actual C application, it would be preferable to use an inlining language feature such as [[parameterized macro]]s or [[inline function]]s to tell the compiler to transform the code in this way. The next section lists ways to optimize this code.&lt;br /&gt;
&lt;br /&gt;
=== Inlining by assembly macro expansion ===&lt;br /&gt;
[[Macro assembler#Macros|Assembler macros]] provide an alternative approach to inlining whereby a sequence of instructions can normally be generated inline by macro expansion from a single macro source statement (with zero or more parameters). One of the parameters might be an option to alternatively generate a one-time separate [[subroutine]] containing the sequence and processed instead by an inlined call to the function.&lt;br /&gt;
Example:&lt;br /&gt;
 MOVE FROM=array1,TO=array2,INLINE=NO&lt;br /&gt;
&lt;br /&gt;
=== Heuristics ===&lt;br /&gt;
A range of different heuristics have been explored for inlining. Usually, an inlining algorithm has a certain code budget (an allowed increase in program size) and aims to inline the most valuable callsites without exceeding that budget. In this sense, many inlining algorithms are usually modeled after the [[Knapsack problem]].&amp;lt;ref&amp;gt;[https://dl.acm.org/citation.cfm?id=359830] Scheifler, An Analysis of Inline Substitution for a Structured Programming Language&amp;lt;/ref&amp;gt; To decide which callsites are more valuable, an inlining algorithm must estimate their benefit—i.e. the expected decrease in the execution time. Commonly, inliners use profiling information about the frequency of the execution of different code paths to estimate the benefits.&amp;lt;ref&amp;gt;[https://dl.acm.org/citation.cfm?id=351416] Matthew Arnold, Stephen Fink, Vivek Sarkar, and Peter F. Sweeney, A Comparative Study of Static and Profile-based Heuristics for Inlining&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to profiling information, newer [[just-in-time compiler]]s apply several more advanced heuristics, such as:&amp;lt;ref name=&amp;quot;prokopec2019&amp;quot;&amp;gt;[https://www.researchgate.net/publication/331408280_An_Optimization-Driven_Incremental_Inline_Substitution_Algorithm_for_Just-in-Time_Compilers] Prokopec et al., An Optimization Driven Incremental Inline Substitution Algorithm for Just-In-Time Compilers, CGO&#039;19 publication about the inliner used in the Graal compiler for the JVM&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Speculating which code paths will result in the best reduction in execution time (by enabling additional compiler optimizations as a result of inlining) and increasing the perceived benefit of such paths.&lt;br /&gt;
* Adaptively adjusting the benefit-per-cost threshold for inlining based on the size of the compiling unit and the amount of code already inlined.&lt;br /&gt;
* Grouping subroutines into clusters, and inlining entire clusters instead of singular subroutines. Here, the heuristic guesses the clusters by grouping those methods for which inlining just a proper subset of the cluster leads to a worse performance than inlining nothing at all.&lt;br /&gt;
&lt;br /&gt;
== Benefits ==&lt;br /&gt;
Inline expansion itself is an optimization, since it eliminates overhead from calls, but it is much more important as an [[enabling transformation]]. That is, once the compiler expands a function body in the context of its call site—often with arguments that may be fixed [[Constant (mathematics)|constants]]—it may be able to do a variety of transformations that were not possible before. For example, a [[conditional branch]] may turn out to be always true or always false at this particular call site. This in turn may enable [[dead code elimination]], [[loop-invariant code motion]], or [[induction variable elimination]].&lt;br /&gt;
&amp;lt;!-- Need to talk more about how to automatically choose which functions to inline&lt;br /&gt;
Need to talk more about inlining recursive functions --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the C example in the prior section, optimizing opportunities abound. The compiler may follow this sequence of steps:&lt;br /&gt;
* The &amp;lt;code&amp;gt;tmp += 0&amp;lt;/code&amp;gt; statements in the lines marked (2) and (3) do nothing. The compiler can remove them.&lt;br /&gt;
* The condition &amp;lt;code&amp;gt;0 == 0&amp;lt;/code&amp;gt; is always true, so the compiler can replace the line marked (2) with the consequent, &amp;lt;code&amp;gt;tmp += 0&amp;lt;/code&amp;gt; (which does nothing).&lt;br /&gt;
* The compiler can rewrite the condition &amp;lt;code&amp;gt;y+1 == 0&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;y == -1&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The compiler can reduce the expression &amp;lt;code&amp;gt;(y + 1) - 1&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The expressions &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y+1&amp;lt;/code&amp;gt; cannot both equal zero. This lets the compiler eliminate one test.&lt;br /&gt;
* In statements such as &amp;lt;code&amp;gt;if (y == 0) return y&amp;lt;/code&amp;gt; the value of &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; is known in the body, and can be inlined.&lt;br /&gt;
The new function looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int func(int y) {&lt;br /&gt;
    if (y == 0) {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
    if (y == -1) {&lt;br /&gt;
        return -2;&lt;br /&gt;
    }&lt;br /&gt;
    return 2 * y - 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Limits ==&lt;br /&gt;
Complete inline expansion is not always possible, due to [[Recursion (computer science)|recursion]]: recursively inline expanding the calls will not terminate. There are various solutions, such as expanding a bounded amount, or analyzing the [[call graph]] and breaking loops at certain nodes (i.e., not expanding some edge in a recursive loop).{{sfn|Peyton Jones|Marlow|1999|loc=4. Ensuring Termination, pp. 6–9}} An identical problem occurs in macro expansion, as recursive expansion does not terminate, and is typically resolved by forbidding recursive macros (as in C and C++).&lt;br /&gt;
&lt;br /&gt;
== Comparison with macros ==&lt;br /&gt;
Traditionally, in languages such as [[C (programming language)|C]], inline expansion was accomplished at the source level using [[parameterized macro]]s. Use of true inline functions, as are available in [[C99]], provides several benefits over this approach:&lt;br /&gt;
* In C, macro invocations do not perform [[type checking]], or even check that arguments are well-formed, whereas function calls usually do.&lt;br /&gt;
* In C, a macro cannot use the return keyword with the same meaning as a function would do (it would make the function that asked the expansion terminate, rather than the macro). In other words, a macro cannot return anything which is not the result of the last expression invoked inside it.&lt;br /&gt;
* Since C macros use mere textual substitution, this may result in unintended side-effects and inefficiency due to re-evaluation of arguments and [[order of operations]].&lt;br /&gt;
* Compiler errors within macros are often difficult to understand, because they refer to the expanded code, rather than the code the programmer typed. Thus, debugging information for inlined code is usually more helpful than that of macro-expanded code.&lt;br /&gt;
* Many constructs are awkward or impossible to express using macros, or use a significantly different syntax. Inline functions use the same syntax as regular functions, and can be inlined and un-inlined at will with ease.&lt;br /&gt;
Many compilers can also inline expand some [[Recursion (computer science)|recursive functions]];&amp;lt;ref&amp;gt;[https://web.archive.org/web/20041013180231/http://home.pipeline.com/~hbaker1/Inlines.html Inlining Semantics for Subroutines which are Recursive]&amp;quot; by Henry G. Baker&amp;lt;/ref&amp;gt; recursive macros are typically illegal.&lt;br /&gt;
&lt;br /&gt;
[[Bjarne Stroustrup]], the designer of C++, likes to emphasize that macros should be avoided wherever possible, and advocates extensive use of inline functions.&lt;br /&gt;
&lt;br /&gt;
== Selection methods ==&lt;br /&gt;
Many compilers aggressively inline functions wherever it is beneficial to do so. Although it can lead to larger [[executable]]s, aggressive inlining has nevertheless become more and more desirable as memory capacity has increased faster than CPU speed. Inlining is a critical optimization in languages for [[Functional programming|functional]] and [[object-oriented programming]], which rely on it to provide enough context for their typically small functions to make classical optimizations effective.&lt;br /&gt;
&lt;br /&gt;
== Language support ==&lt;br /&gt;
Many languages, including [[Java (programming language)|Java]] and functional languages, do not provide language constructs for inline functions, but their compilers or [[Interpreter (computing)|interpreters]] often perform aggressive inline expansion.&amp;lt;ref name=&amp;quot;prokopec2019&amp;quot;/&amp;gt; Other languages provide constructs for explicit hints, generally as compiler [[Directive (programming)|directives]] (pragmas).&lt;br /&gt;
&lt;br /&gt;
The language [[Ada (programming language)|Ada]] has a pragma for inline functions.&lt;br /&gt;
&lt;br /&gt;
Functions in [[Common Lisp]] may be defined as inline by the &amp;lt;code&amp;gt;inline&amp;lt;/code&amp;gt; declaration as such:&amp;lt;ref&amp;gt;[http://www.lispworks.com/documentation/HyperSpec/Body/d_inline.htm#inline &#039;&#039;Declaration&#039;&#039; &#039;&#039;&#039;INLINE&#039;&#039;&#039;, &#039;&#039;&#039;NOTINLINE&#039;&#039;&#039;] at the [[Common Lisp HyperSpec]]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lisp&amp;quot;&amp;gt;&lt;br /&gt;
 (declaim (inline dispatch))&lt;br /&gt;
 (defun dispatch (x)&lt;br /&gt;
   (funcall&lt;br /&gt;
     (get (car x) &#039;dispatch) x))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [[Haskell]] compiler [[Glasgow Haskell Compiler|GHC]] tries to inline functions or values that are small enough but inlining may be noted explicitly using a language pragma:&amp;lt;ref&amp;gt;[http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/pragmas.html 7.13.5.1. INLINE pragma] Chapter 7. GHC Language Features&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;haskell&amp;quot;&amp;gt;&lt;br /&gt;
key_function :: Int -&amp;gt; String -&amp;gt; (Bool, Double)&lt;br /&gt;
{-# INLINE key_function #-}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C and C++ ===&lt;br /&gt;
{{Further|Inline function}}&lt;br /&gt;
[[C (programming language)|C]] and [[C++]] have an &amp;lt;code&amp;gt;inline&amp;lt;/code&amp;gt; keyword which serves as a hint that inlining may be beneficial; however, in newer versions, its main purpose is instead to alter the visibility and linking behavior of the function.&amp;lt;ref&amp;gt;https://en.cppreference.com/w/cpp/language/inline {{Bare URL inline|date=August 2025}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
In [[Rust (programming language)|Rust]], inlining is automatically done by the compiler.&amp;lt;ref name=&amp;quot;rust-ref-inline&amp;quot;&amp;gt;{{Cite web |title=Code generation - The Rust Reference |url=https://doc.rust-lang.org/nightly/reference/attributes/codegen.html?highlight=inline#r-attributes.codegen.inline |access-date=2025-05-01 |website=doc.rust-lang.org}}&amp;lt;/ref&amp;gt; Rust provides an &amp;lt;code&amp;gt;#[inline]&amp;lt;/code&amp;gt; attribute that suggests to the compiler that a function should be inlined, but does not guarantee it; the compiler may ignore even &amp;lt;code&amp;gt;#[inline(always)]&amp;lt;/code&amp;gt;. In debug mode, the compiler will never inline.&amp;lt;ref name=&amp;quot;rust-stddev-inlining&amp;quot;&amp;gt;{{Cite web |title=When to #[inline] - Standard library developers Guide |url=https://std-dev-guide.rust-lang.org/policy/inline.html |access-date=2025-05-01 |website=std-dev-guide.rust-lang.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Macro (computer science)]]&lt;br /&gt;
* [[Partial evaluation]]&lt;br /&gt;
* [[Tail-call elimination]]&lt;br /&gt;
* [[Code outlining]]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
{{Notelist}}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
* {{Cite journal |last1=Chen |first1=W. Y. |last2=Chang |first2=P. P. |last3=Conte |first3=T. M. |last4=Hwu |first4=W. W. |date=September 1993 |title=The effect of code expanding optimizations on instruction cache design |url=http://impact.crhc.illinois.edu/shared/report/crhc-91-17.icache.pdf |journal=IEEE Transactions on Computers |volume=42 |issue=9 |pages=1045–1057 |doi=10.1109/12.241594 |bibcode=1993ITCmp..42.1045C |hdl=2142/74513 |hdl-access=free}}&lt;br /&gt;
* {{cite tech report |last1=Peyton Jones |first1=Simon |author1-link=Simon Peyton Jones |last2=Marlow |first2=Simon |author2-link=Simon Marlow |date=September 1999 |url=http://research.microsoft.com/~simonpj/Papers/inlining/ |title=Secrets of the Glasgow Haskell Compiler Inliner}}&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
{{Wiktionary|in-line expansion|inlining}}&lt;br /&gt;
*&amp;quot;[http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.114.1036 Eliminating Virtual Function Calls in C++ Programs]&amp;quot;; Gerald Aigner, [[Urs Hölzle]]&lt;br /&gt;
*&amp;quot;[http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.187.7208 Reducing Indirect Function Call Overhead In C++ Programs]&amp;quot;; Brad Calder, Dirk Grumwald&lt;br /&gt;
*[https://web.archive.org/web/20060907183845/http://www.cs.arizona.edu/alto/Doc/alto.html ALTO - A Link-Time Optimizer for the DEC Alpha]&lt;br /&gt;
*&amp;quot;[https://web.archive.org/web/20160303171839/http://www.iecc.com/linker/linker11.html Advanced techniques]&amp;quot;; [[John R. Levine]]&lt;br /&gt;
*&amp;quot;[https://web.archive.org/web/20041010124209/http://www.codeproject.com/tips/gloption.asp Whole Program Optimization with Visual C++ .NET]&amp;quot;; Brandon Bray&lt;br /&gt;
&lt;br /&gt;
{{Compiler optimizations}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Compiler optimizations]]&lt;br /&gt;
[[Category:Subroutines]]&lt;br /&gt;
[[Category:Programming language comparisons]]&lt;br /&gt;
&amp;lt;!-- Hidden categories below --&amp;gt;&lt;br /&gt;
[[Category:Articles with example C code]]&lt;br /&gt;
[[Category:Articles with example Haskell code]]&lt;br /&gt;
[[Category:Articles with example Lisp (programming language) code]]&lt;/div&gt;</summary>
		<author><name>2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF</name></author>
	</entry>
	<entry>
		<id>https://wiki.sarg.dev/index.php?title=Tail_call&amp;diff=647242</id>
		<title>Tail call</title>
		<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php?title=Tail_call&amp;diff=647242"/>
		<updated>2025-10-19T16:07:33Z</updated>

		<summary type="html">&lt;p&gt;2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF: /* C example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Short description|Subroutine call performed as final action of a procedure}}&lt;br /&gt;
In [[computer science]], a &#039;&#039;&#039;tail call&#039;&#039;&#039; is a [[subroutine]] call performed as the final action of a procedure.&amp;lt;ref name=&amp;quot;MuchnickAssociates1997&amp;quot;&amp;gt;&lt;br /&gt;
{{Cite book&lt;br /&gt;
| author1    = Steven Muchnick&lt;br /&gt;
| author2    = Muchnick and Associates&lt;br /&gt;
| date       = 15 August 1997&lt;br /&gt;
| isbn       = 978-1-55860-320-2&lt;br /&gt;
| publisher  = Morgan Kaufmann&lt;br /&gt;
| title      = Advanced Compiler Design Implementation&lt;br /&gt;
| url        = https://archive.org/details/advancedcompiler00much&lt;br /&gt;
| url-access = registration&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
If the target of a tail is the same subroutine, the subroutine is said to be &#039;&#039;&#039;tail recursive&#039;&#039;&#039;, which is a special case of direct [[recursion (computer science)|recursion]]. &#039;&#039;&#039;Tail recursion&#039;&#039;&#039; (or &#039;&#039;&#039;tail-end recursion&#039;&#039;&#039;) is particularly useful, and is often easy to optimize in implementations. &lt;br /&gt;
&lt;br /&gt;
Tail calls can be implemented without adding a new [[stack frame]] to the [[call stack]]. Most of the frame of the current procedure is no longer needed, and can be replaced by the frame of the tail call, modified as appropriate (similar to [[Exec (system call)|overlay]] for processes, but for function calls). The program can then [[jump (computer science)|jump]] to the called subroutine. Producing such code instead of a standard call sequence is called &#039;&#039;&#039;tail-call elimination&#039;&#039;&#039; or &#039;&#039;&#039;tail-call optimization&#039;&#039;&#039;. Tail-call elimination allows procedure calls in tail position to be implemented as efficiently as [[goto]] statements, thus allowing efficient [[structured programming]]. In the words of [[Guy L. Steele]], &amp;quot;in general, procedure calls may be usefully thought of as GOTO statements which also pass parameters, and can be uniformly coded as [machine code] JUMP instructions.&amp;quot;&amp;lt;ref name=&amp;quot;aim-443&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Not all programming languages require tail-call elimination. However, in [[functional programming language]]s, tail-call elimination is often guaranteed by the [[Programming language specification|language standard]], allowing tail recursion to use a similar amount of memory as an equivalent [[loop (computing)|loop]]. The special case of tail-recursive calls, when a function calls itself, may be more amenable to call elimination than general tail calls. When the language semantics do not explicitly support general tail calls, a compiler can often still optimize &#039;&#039;&#039;sibling calls&#039;&#039;&#039;, or tail calls to functions which take and return the same types as the caller.&amp;lt;ref name=&amp;quot;llvm.org&amp;quot;&amp;gt;&lt;br /&gt;
{{Cite web&lt;br /&gt;
| url     = http://llvm.org/docs/CodeGenerator.html#sibling-call-optimization&lt;br /&gt;
| title   = The LLVM Target-Independent Code Generator — LLVM 7 documentation&lt;br /&gt;
| website = llvm.org&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
When a function is called, the computer must &amp;quot;remember&amp;quot; the place it was called from, the &#039;&#039;[[Return address (computing)|return address]]&#039;&#039;, so that it can return to that location with the result once the call is complete. Typically, this information is saved on the [[call stack]], a list of return locations in the order that the call locations were reached. In addition, compilers allocate memory for local variables of the called function and push register content (if any and/or relevant) onto the stack. Typically, it is done by allocating a stack frame including saved registers, space allocated for non-register local variables, return address and call parameters (unless they are passed in registers). For tail calls, there is no need to remember the caller or preserve content of registers – instead, tail-call elimination avoids allocation of new stack frames and makes only the minimum necessary changes to the existing stack frame before passing it on, and the tail-called function will return directly to the &#039;&#039;original&#039;&#039; caller.&amp;lt;ref&amp;gt;&lt;br /&gt;
{{Cite web&lt;br /&gt;
| access-date = 2013-03-21&lt;br /&gt;
| date        = 2011-07-29&lt;br /&gt;
| publisher   = Cstheory.stackexchange.com&lt;br /&gt;
| title       = recursion - Stack memory usage for tail calls - Theoretical Computer Science&lt;br /&gt;
| url         = https://cstheory.stackexchange.com/q/7540&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
This, however, leads to complete loss of the caller&#039;s stack frame, which is sometimes considered as a hindrance in debugging. The tail call doesn&#039;t have to appear lexically after all other statements in the source code; it is only important that the calling function return immediately after the tail call, returning the tail call&#039;s result if any, since the calling function is bypassed when the optimization is performed.&lt;br /&gt;
&lt;br /&gt;
For non-recursive function calls, this is usually an [[Program optimization|optimization]] that saves only a little time and space, since there are not that many different functions available to call. When dealing with recursive or [[mutually recursive]] functions where recursion happens through tail calls, however, the stack space and the number of returns saved can grow to be very significant, since a function can call itself, directly or indirectly, creating a new call stack frame each time. Tail-call elimination often reduces asymptotic stack space requirements from linear, or [[Big-O notation|O]](n), to constant, or [[Big-O notation|O]](1). Tail-call elimination is thus required by the standard definitions of some programming languages, such as [[Scheme (programming language)|Scheme]], and languages in the [[ML (programming language)|ML]] family among others.&amp;lt;ref name=&#039;SchemeProperTailRec&#039;&amp;gt;&lt;br /&gt;
{{Cite web&lt;br /&gt;
| access-date = 2013-03-21&lt;br /&gt;
| publisher   = R6rs.org&lt;br /&gt;
| title       = Revised [6] Report on the Algorithmic Language Scheme &lt;br /&gt;
| url         = http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-8.html#node_sec_5.11 &lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;&lt;br /&gt;
{{Cite web&lt;br /&gt;
| access-date = 2013-03-21&lt;br /&gt;
| publisher   = R6rs.org&lt;br /&gt;
| title       = Revised [6] Report on the Algorithmic Language Scheme - Rationale &lt;br /&gt;
| url         = http://www.r6rs.org/final/html/r6rs-rationale/r6rs-rationale-Z-H-7.html#node_sec_5.3&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
The Scheme language definition formalizes the intuitive notion of tail position exactly, by specifying which syntactic forms allow having results in tail context.&amp;lt;ref&amp;gt;&lt;br /&gt;
{{Cite web&lt;br /&gt;
| access-date = 2013-03-21&lt;br /&gt;
| publisher   = R6rs.org&lt;br /&gt;
| title       = Revised [6] Report on the Algorithmic Language Scheme &lt;br /&gt;
| url         = http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.20 &lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
Implementations allowing an unlimited number of tail calls to be active at the same moment, thanks to tail-call elimination, can also be called &#039;properly tail recursive&#039;.&amp;lt;ref name=&#039;SchemeProperTailRec&#039;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besides space and execution efficiency, tail-call elimination is important in the [[functional programming]] idiom known as [[continuation-passing style]] (CPS), which would otherwise quickly run out of stack space.&lt;br /&gt;
&lt;br /&gt;
== Syntactic form ==&lt;br /&gt;
&lt;br /&gt;
A tail call can be located just before the syntactical end of a function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function foo(data) {&lt;br /&gt;
    a(data);&lt;br /&gt;
    return b(data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, both &amp;lt;code&amp;gt;a(data)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;b(data)&amp;lt;/code&amp;gt; are calls, but &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; is the last thing the procedure executes before returning and is thus in tail position. However, not all tail calls are necessarily located at the syntactical end of a subroutine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function bar(data) {&lt;br /&gt;
    if (a(data)) {&lt;br /&gt;
        return b(data);&lt;br /&gt;
    }&lt;br /&gt;
    return c(data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, both calls to &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; are in tail position. This is because each of them lies in the end of if-branch respectively, even though the first one is not syntactically at the end of &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt;&#039;s body.&lt;br /&gt;
&lt;br /&gt;
In this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function foo1(data) {&lt;br /&gt;
    return a(data) + 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function foo2(data) {&lt;br /&gt;
    var ret = a(data);&lt;br /&gt;
    return ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function foo3(data) {&lt;br /&gt;
    var ret = a(data);&lt;br /&gt;
    return (ret == 0) ? 1 : ret;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the call to &amp;lt;code&amp;gt;a(data)&amp;lt;/code&amp;gt; is in tail position in &amp;lt;code&amp;gt;foo2&amp;lt;/code&amp;gt;, but it is &#039;&#039;&#039;not&#039;&#039;&#039; in tail position either in &amp;lt;code&amp;gt;foo1&amp;lt;/code&amp;gt; or in &amp;lt;code&amp;gt;foo3&amp;lt;/code&amp;gt;, because control must return to the caller to allow it to inspect or modify the return value before returning it.&lt;br /&gt;
&lt;br /&gt;
==Example programs==&lt;br /&gt;
The following program is an example in [[Scheme (programming language)|Scheme]]:&amp;lt;ref name=&amp;quot;sicp&amp;quot;&amp;gt;{{cite book|last1=Sussman|first1=G. J.|last2=Abelson|first2=Hal|title=Structure and Interpretation of Computer Programs|date=1984|publisher=MIT Press|location=Cambridge, MA|isbn=0-262-01077-1|url=https://archive.org/details/structureinterpr00abel}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
;; factorial : number -&amp;gt; number&lt;br /&gt;
;; to calculate the product of all positive&lt;br /&gt;
;; integers less than or equal to n.&lt;br /&gt;
(define (factorial n)&lt;br /&gt;
 (if (= n 0)&lt;br /&gt;
    1&lt;br /&gt;
    (* n (factorial (- n 1)))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is not written in a tail-recursive style, because the multiplication function (&amp;quot;*&amp;quot;) is in the tail position. This can be compared to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
;; factorial : number -&amp;gt; number&lt;br /&gt;
;; to calculate the product of all positive&lt;br /&gt;
;; integers less than or equal to n.&lt;br /&gt;
(define (factorial n)&lt;br /&gt;
  (fact-iter 1 n))&lt;br /&gt;
(define (fact-iter product n)&lt;br /&gt;
  (if (= n 0)&lt;br /&gt;
      product&lt;br /&gt;
      (fact-iter (* product n)&lt;br /&gt;
                 (- n 1))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This program assumes [[Evaluation strategy#Applicative order|applicative-order]] evaluation. The inner procedure &amp;lt;code&amp;gt;fact-iter&amp;lt;/code&amp;gt; calls itself &#039;&#039;last&#039;&#039; in the control flow. This allows an [[interpreter (computer software)|interpreter]] or [[compiler]] to reorganize the execution which would ordinarily look like this:&amp;lt;ref name=&amp;quot;sicp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   call factorial (4)&lt;br /&gt;
    call fact-iter (1 4)&lt;br /&gt;
     call fact-iter (4 3)&lt;br /&gt;
      call fact-iter (12 2)&lt;br /&gt;
       call fact-iter (24 1)&lt;br /&gt;
       return 24&lt;br /&gt;
      return 24&lt;br /&gt;
     return 24&lt;br /&gt;
    return 24&lt;br /&gt;
   return 24&lt;br /&gt;
&lt;br /&gt;
into the more [[Algorithmic efficiency|efficient]] variant, in terms of both space and time:&lt;br /&gt;
&lt;br /&gt;
   call factorial (4)&lt;br /&gt;
    call fact-iter (1 4)&lt;br /&gt;
    replace arguments with (4 3)&lt;br /&gt;
    replace arguments with (12 2)&lt;br /&gt;
    replace arguments with (24 1)&lt;br /&gt;
    return 24&lt;br /&gt;
   return 24&lt;br /&gt;
&lt;br /&gt;
This reorganization saves space because no state except for the calling function&#039;s address needs to be saved, either on the stack or on the heap, and the call stack frame for &amp;lt;code&amp;gt;fact-iter&amp;lt;/code&amp;gt; is reused for the intermediate results storage. This also means that the programmer need not worry about running out of stack or heap space for extremely deep recursions. In typical implementations, the tail-recursive variant will be substantially faster than the other variant, but only by a constant factor.&lt;br /&gt;
&lt;br /&gt;
Some programmers working in functional languages will rewrite recursive code to be tail recursive so they can take advantage of this feature. This often requires addition of an &amp;quot;accumulator&amp;quot; argument (&amp;lt;code&amp;gt;product&amp;lt;/code&amp;gt; in the above example) to the function. &lt;br /&gt;
&lt;br /&gt;
==Tail recursion modulo cons==&lt;br /&gt;
&#039;&#039;&#039;Tail recursion modulo cons&#039;&#039;&#039; is a generalization of tail-recursion optimization introduced by [[David H. D. Warren]]&amp;lt;ref&amp;gt;D. H. D. Warren, &#039;&#039;DAI Research Report 141&#039;&#039;, University of Edinburgh, 1980.&amp;lt;/ref&amp;gt; in the context of [[compiler|compilation]] of [[Prolog]], seen as an &#039;&#039;explicitly&#039;&#039; [[Single assignment#Single assignment|&#039;&#039;set once&#039;&#039;]] language. It was described (though not named) by [[Daniel P. Friedman]] and [[David S. Wise]] in 1974&amp;lt;ref&amp;gt;Daniel P. Friedman and David S. Wise, [http://www.cs.indiana.edu/cgi-bin/techreports/TRNNN.cgi?trnum=TR19 &#039;&#039;Technical Report TR19: Unwinding Structured Recursions into Iterations&#039;&#039;], Indiana University, Dec. 1974. PDF available [https://legacy.cs.indiana.edu/ftp/techreports/TR19.pdf &#039;&#039;here&#039;&#039;] (webarchived copy [https://web.archive.org/web/20221023082940/https://legacy.cs.indiana.edu/ftp/techreports/TR19.pdf &#039;&#039;here&#039;&#039;]).&amp;lt;/ref&amp;gt; as a [[LISP]] compilation technique. As the name suggests, it applies when the only operation left to perform after a recursive call is to prepend a known value in front of the list returned from it (or to perform a constant number of simple data-constructing operations, in general). This call would thus be a &#039;&#039;tail call&#039;&#039; save for (&amp;quot;[[modulo (jargon)|modulo]]&amp;quot;) the said &#039;&#039;[[cons]]&#039;&#039; operation. But prefixing a value at the start of a list &#039;&#039;on exit&#039;&#039; from a recursive call is the same as appending this value at the end of the growing list &#039;&#039;on entry&#039;&#039; into the recursive call, thus building the list as a [[side effect (computer science)|side effect]], as if in an implicit accumulator parameter. The following Prolog fragment illustrates the concept:&lt;br /&gt;
&lt;br /&gt;
===Example code===&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
% Prolog, tail recursive modulo cons:&lt;br /&gt;
partition([], _, [], []).&lt;br /&gt;
partition([X|Xs], Pivot, [X|Rest], Bigs) :-&lt;br /&gt;
  X @&amp;lt; Pivot, !,&lt;br /&gt;
  partition(Xs, Pivot, Rest, Bigs).&lt;br /&gt;
partition([X|Xs], Pivot, Smalls, [X|Rest]) :-&lt;br /&gt;
  partition(Xs, Pivot, Smalls, Rest).&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;haskell&amp;quot;&amp;gt;&lt;br /&gt;
-- In Haskell, guarded recursion:&lt;br /&gt;
partition [] _ = ([],[])&lt;br /&gt;
partition (x:xs) p &lt;br /&gt;
        | x &amp;lt; p     = (x:a,b)&lt;br /&gt;
        | otherwise = (a,x:b)&lt;br /&gt;
   where&lt;br /&gt;
      (a,b) = partition xs p&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
% Prolog, with explicit unifications:&lt;br /&gt;
%     non-tail recursive translation:&lt;br /&gt;
partition([], _, [], []).&lt;br /&gt;
partition(L, Pivot, Smalls, Bigs) :- L=[X|Xs],&lt;br /&gt;
 (  X @&amp;lt; Pivot&lt;br /&gt;
 -&amp;gt; partition(Xs,Pivot,Rest,Bigs), Smalls=[X|Rest]&lt;br /&gt;
 ;  partition(Xs,Pivot,Smalls,Rest), Bigs=[X|Rest]&lt;br /&gt;
 ).&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
% Prolog, with explicit unifications:&lt;br /&gt;
%     tail-recursive translation:&lt;br /&gt;
partition([], _, [], []).&lt;br /&gt;
partition(L, Pivot, Smalls, Bigs) :- L=[X|Xs],&lt;br /&gt;
 (  X @&amp;lt; Pivot&lt;br /&gt;
 -&amp;gt; Smalls=[X|Rest], partition(Xs,Pivot,Rest,Bigs)&lt;br /&gt;
 ;  Bigs=[X|Rest], partition(Xs,Pivot,Smalls,Rest)&lt;br /&gt;
 ).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Thus in tail-recursive translation such a call is transformed into first creating a new [[Node (computer science)|list node]] and setting its &amp;lt;code&amp;gt;first&amp;lt;/code&amp;gt; field, and &#039;&#039;then&#039;&#039; making the tail call with the pointer to the node&#039;s &amp;lt;code&amp;gt;rest&amp;lt;/code&amp;gt; field as argument, to be filled recursively. The same effect is achieved when the recursion is &#039;&#039;guarded&#039;&#039; under a lazily evaluated data constructor, which is automatically achieved in lazy programming languages like Haskell.&lt;br /&gt;
&lt;br /&gt;
===C example===&lt;br /&gt;
The following fragment defines a recursive function in [[C (programming language)|C]] that duplicates a linked list (with some equivalent Scheme and Prolog code as comments, for comparison):&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct LinkedList {&lt;br /&gt;
    void* value;&lt;br /&gt;
    struct LinkedList* next;&lt;br /&gt;
} LinkedList;&lt;br /&gt;
&lt;br /&gt;
LinkedList* duplicate(const LinkedList** ls) {&lt;br /&gt;
    LinkedList* head = NULL;&lt;br /&gt;
&lt;br /&gt;
    if (ls) {&lt;br /&gt;
        LinkedList* p = duplicate(ls-&amp;gt;next);&lt;br /&gt;
        head = (LinkedList*)malloc(sizeof(*head));&lt;br /&gt;
        head-&amp;gt;value = ls-&amp;gt;value;&lt;br /&gt;
        head-&amp;gt;next = p;&lt;br /&gt;
    }&lt;br /&gt;
    return head;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
;; in Scheme,&lt;br /&gt;
(define (duplicate ls)&lt;br /&gt;
  (if (not (null? ls))&lt;br /&gt;
    (cons (car ls)&lt;br /&gt;
          (duplicate (cdr ls)))&lt;br /&gt;
    &#039;()))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
%% in Prolog,&lt;br /&gt;
duplicate([X|Xs],R):-&lt;br /&gt;
  duplicate(Xs,Ys),&lt;br /&gt;
  R=[X|Ys].&lt;br /&gt;
duplicate([],[]).&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In this form the function is not tail recursive, because control returns to the caller after the recursive call duplicates the rest of the input list. Even if it were to allocate the &#039;&#039;head&#039;&#039; node before duplicating the rest, it would still need to plug in the result of the recursive call into the &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt; field &#039;&#039;after&#039;&#039; the call.{{efn|Like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (ls) {&lt;br /&gt;
    head = (LinkedList*)malloc(sizeof(*head));&lt;br /&gt;
    head-&amp;gt;value = ls-&amp;gt;value;&lt;br /&gt;
    head-&amp;gt;next = duplicate(ls-&amp;gt;next);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
So the function is &#039;&#039;almost&#039;&#039; tail recursive. Warren&#039;s method pushes the responsibility of filling the &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt; field into the recursive call itself, which thus becomes tail call.{{efn|Like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (ls) {&lt;br /&gt;
    head = (LinkedList*)malloc(sizeof(*head));&lt;br /&gt;
    head-&amp;gt;value = ls-&amp;gt;value;&lt;br /&gt;
    duplicate(ls-&amp;gt;next, &amp;amp;(head-&amp;gt;next));&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}} Using  sentinel head node to simplify the code, &lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void duplicate_aux(const LinkedList* ls, LinkedList* end) {&lt;br /&gt;
    if (ls) {&lt;br /&gt;
        end-&amp;gt;next = (LinkdList*)malloc(sizeof(*end));&lt;br /&gt;
        end-&amp;gt;next-&amp;gt;value = ls-&amp;gt;value;&lt;br /&gt;
        duplicate_aux(ls-&amp;gt;next, end-&amp;gt;next);&lt;br /&gt;
    } else {&lt;br /&gt;
        end-&amp;gt;next = NULL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
LinkedList* duplicate(const LinkedList* ls) {  &lt;br /&gt;
    LinkedList head;&lt;br /&gt;
&lt;br /&gt;
    duplicate_aux(ls, &amp;amp;head);&lt;br /&gt;
    return head.next;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
;; in Scheme,&lt;br /&gt;
(define (duplicate ls)&lt;br /&gt;
  (let ((head (list 1)))&lt;br /&gt;
    (let dup ((ls  ls)&lt;br /&gt;
              (end head))&lt;br /&gt;
      (cond&lt;br /&gt;
        ((not (null? ls))&lt;br /&gt;
         (set-cdr! end (list (car ls)))&lt;br /&gt;
         (dup (cdr ls) (cdr end)))))&lt;br /&gt;
    (cdr head)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
%% in Prolog,&lt;br /&gt;
duplicate([X|Xs],R):-&lt;br /&gt;
   R=[X|Ys],&lt;br /&gt;
   duplicate(Xs,Ys).&lt;br /&gt;
duplicate([],[]).&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The callee now appends to the end of the growing list, rather than have the caller prepend to the beginning of the returned list. The work is now done on the way &#039;&#039;forward&#039;&#039; from the list&#039;s start, &#039;&#039;before&#039;&#039; the recursive call which then proceeds further, instead of &#039;&#039;backward&#039;&#039; from the list&#039;s end, &#039;&#039;after&#039;&#039; the recursive call has returned its result. It is thus similar to the accumulating parameter technique, turning a recursive computation into an iterative one.&lt;br /&gt;
&lt;br /&gt;
Characteristically for this technique, a parent [[call frame|frame]] is created on the execution call stack, which the tail-recursive callee can reuse as its own call frame if the tail-call optimization is present.&lt;br /&gt;
&lt;br /&gt;
The tail-recursive implementation can now be converted into an explicitly iterative implementation, as an accumulating [[Loop (computing)#Loops|loop]]:&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
LinkedList* duplicate(const LinkedList* ls) {&lt;br /&gt;
    LinkedList head;&lt;br /&gt;
    LinkedList* end;&lt;br /&gt;
    end = &amp;amp;head;&lt;br /&gt;
    while (ls) {&lt;br /&gt;
        end-&amp;gt;next = (LinkedList*)malloc(sizeof(*end));&lt;br /&gt;
        end-&amp;gt;next-&amp;gt;value = ls-&amp;gt;value;&lt;br /&gt;
        ls = ls-&amp;gt;next;&lt;br /&gt;
        end = end-&amp;gt;next;&lt;br /&gt;
    }&lt;br /&gt;
    end-&amp;gt;next = NULL;&lt;br /&gt;
    return head.next;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 ;; in Scheme,&lt;br /&gt;
 (define (duplicate ls)&lt;br /&gt;
   (let ((head (list 1)))&lt;br /&gt;
     (do ((end head (cdr end))&lt;br /&gt;
          (ls  ls   (cdr ls )))&lt;br /&gt;
         ((null? ls) (cdr head))&lt;br /&gt;
       (set-cdr! end (list (car ls))))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;prolog&amp;quot;&amp;gt;&lt;br /&gt;
%% in Prolog,&lt;br /&gt;
%% N/A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
In a paper delivered to the [[Association for Computing Machinery|ACM]] conference in Seattle in 1977, [[Guy L. Steele]] summarized the debate over the [[GOTO]] and [[structured programming]], and observed that procedure calls in the tail position of a procedure can be best treated as a direct transfer of control to the called procedure, typically eliminating unnecessary stack manipulation operations.&amp;lt;ref name=&amp;quot;aim-443&amp;quot;&amp;gt;{{Cite book|doi=10.1145/800179.810196|isbn=978-1-4503-2308-6|hdl=1721.1/5753|chapter=Debunking the “expensive procedure call” myth or, procedure call implementations considered harmful or, LAMBDA: The Ultimate GOTO|title=Proceedings of the 1977 annual conference on - ACM &#039;77|year=1977|last1=Steele|first1=Guy Lewis|pages=153–162 |s2cid=9807843}}&amp;lt;/ref&amp;gt; Since such &amp;quot;tail calls&amp;quot; are very common in [[Lisp (programming language)|Lisp]], a language where procedure calls are ubiquitous, this form of optimization considerably reduces the cost of a procedure call compared to other implementations. Steele argued that poorly-implemented procedure calls had led to an artificial perception that the GOTO was cheap compared to the procedure call. Steele further argued that &amp;quot;in general procedure calls may be usefully thought of as GOTO statements which also pass parameters, and can be uniformly coded as [machine code] JUMP instructions&amp;quot;, with the machine code stack manipulation instructions &amp;quot;considered an optimization (rather than vice versa!)&amp;quot;.&amp;lt;ref name=&amp;quot;aim-443&amp;quot;/&amp;gt; Steele cited evidence that well-optimized numerical algorithms in Lisp could execute faster than code produced by then-available commercial Fortran compilers because the cost of a procedure call in Lisp was much lower. In [[Scheme (programming language)|Scheme]], a Lisp dialect developed by Steele with [[Gerald Jay Sussman]], tail-call elimination is guaranteed to be implemented in any interpreter.&amp;lt;ref name=&amp;quot;r5rs&amp;quot;&amp;gt;R5RS Sec. 3.5, {{Cite journal&lt;br /&gt;
|author1=Richard Kelsey |author2=William Clinger |author3=Jonathan Rees |date=August 1998&lt;br /&gt;
| title = Revised&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt; Report on the Algorithmic Language Scheme&lt;br /&gt;
| url = http://www.schemers.org/Documents/Standards/R5RS/&lt;br /&gt;
| journal = Higher-Order and Symbolic Computation&lt;br /&gt;
| volume = 11&lt;br /&gt;
| issue = 1&lt;br /&gt;
| pages = 7–105&lt;br /&gt;
| doi = 10.1023/A:1010051815785&lt;br /&gt;
|s2cid=14069423 |display-authors=etal| url-access = subscription&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Implementation methods==&lt;br /&gt;
Tail recursion is important to some [[high-level programming language|high-level languages]], especially [[functional programming|functional]] and [[logic programming|logic]] languages and members of the [[Lisp programming language|Lisp]] family. In these languages, tail recursion is the most commonly used way (and sometimes the only way available) of implementing iteration. The language specification of Scheme requires that tail calls are to be optimized so as not to grow the stack. Tail calls can be made explicitly in [[Perl]], with a variant of the &amp;quot;goto&amp;quot; statement that takes a function name: &amp;lt;code&amp;gt;goto &amp;amp;NAME;&amp;lt;/code&amp;gt;&amp;lt;ref&amp;gt;{{cite web|author=Contact details |url=http://perldoc.perl.org/functions/goto.html |title=goto |publisher=perldoc.perl.org |access-date=2013-03-21}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, for language implementations which store function arguments and local variables on a [[call stack]] (which is the default implementation for many languages, at least on systems with a [[hardware stack]], such as the [[x86]]), implementing generalized tail-call optimization (including mutual tail recursion) presents an issue: if the size of the callee&#039;s activation record is different from that of the caller, then additional cleanup or resizing of the stack frame may be required. For these cases, optimizing tail recursion remains trivial, but general tail-call optimization may be harder to implement efficiently.&lt;br /&gt;
&lt;br /&gt;
For example, in the [[Java virtual machine]] (JVM), tail-recursive calls can be eliminated (as this reuses the existing call stack), but general tail calls cannot be (as this changes the call stack).&amp;lt;ref&amp;gt;&amp;quot;[https://stackoverflow.com/questions/12045299/what-is-difference-between-tail-calls-and-tail-recursion What is difference between tail calls and tail recursion?]&amp;quot;, &#039;&#039;Stack Overflow&#039;&#039;&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;&amp;quot;[http://programmers.stackexchange.com/questions/157684/what-limitations-does-the-jvm-impose-on-tail-call-optimization What limitations does the JVM impose on tail-call optimization]&amp;quot;, &#039;&#039;Programmers Stack Exchange&#039;&#039;&amp;lt;/ref&amp;gt; As a result, functional languages such as [[Scala (programming language)|Scala]] that target the JVM can efficiently implement direct tail recursion, but not mutual tail recursion.&lt;br /&gt;
&lt;br /&gt;
The [[GNU Compiler Collection|GCC]], [[Clang|LLVM/Clang]], and [[Intel C Compiler|Intel]] compiler suites perform tail-call optimization for [[C (programming language)|C]] and other languages at higher optimization levels or when the &amp;lt;code&amp;gt;-foptimize-sibling-calls&amp;lt;/code&amp;gt; option is passed.&amp;lt;ref name=&amp;quot;llvm-documentation-tco&amp;quot;&amp;gt;{{cite web |last1=Lattner |first1=Chris |title=LLVM Language Reference Manual, section: The LLVM Target-Independent Code Generator, sub: Tail Call Optimization |url=http://llvm.org/docs/CodeGenerator.html#tail-call-optimization |website=The LLVM Compiler Infrastructure |publisher=The LLVM Project |access-date=24 June 2018 |ref=llvm.org}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web|url=https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html|title=Using the GNU Compiler Collection (GCC): Optimize Options|website=gcc.gnu.org}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=https://software.intel.com/en-us/node/522809 |title=foptimize-sibling-calls|website=software.intel.com}}&amp;lt;/ref&amp;gt; Though the given language syntax may not explicitly support it, the compiler can make this optimization whenever it can determine that the return types for the caller and callee are equivalent, and that the argument types passed to both function are either the same, or require the same amount of total storage space on the call stack.&amp;lt;ref&amp;gt;{{cite web|url=http://www.drdobbs.com/tackling-c-tail-calls/184401756|title=Tackling C++ Tail Calls}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Various implementation methods are available.&lt;br /&gt;
&lt;br /&gt;
===In assembly===&lt;br /&gt;
{{unreferenced section|date=June 2014}}&lt;br /&gt;
Tail calls are often optimized by [[interpreter (computing)|interpreters]] and [[compiler]]s of [[functional programming]] and [[logic programming]] languages to more efficient forms of [[iteration]]. For example, [[Scheme (programming language)|Scheme]] programmers commonly express [[while loop]]s as calls to procedures in tail position and rely on the Scheme compiler or interpreter to substitute the tail calls with more efficient [[jump (computer science)|jump]] instructions.&amp;lt;ref&amp;gt;{{cite web | url=https://gcc.gnu.org/ml/gcc/2000-07/msg00595.html | title=proper tail recursion for gcc | publisher=GCC Project | date=20 July 2000 | access-date=10 March 2015 | author=Probst, Mark}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For compilers generating assembly directly, tail-call elimination is easy: it suffices to replace a call opcode with a jump one, after fixing parameters on the stack. From a compiler&#039;s perspective, the first example above is initially translated into pseudo-[[assembly language]] (in fact, this is valid [[x86 assembly language|x86 assembly]]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
 foo:&lt;br /&gt;
  call B&lt;br /&gt;
  call A&lt;br /&gt;
  ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tail-call elimination replaces the last two lines with a single jump instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 foo:&lt;br /&gt;
  call B&lt;br /&gt;
  jmp  A&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After subroutine &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; completes, it will then return directly to the return address of &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;, omitting the unnecessary &amp;lt;code&amp;gt;ret&amp;lt;/code&amp;gt; statement.&lt;br /&gt;
&lt;br /&gt;
Typically, the subroutines being called need to be supplied with [[parameter (computer science)|parameter]]s. The generated code thus needs to make sure that the [[call frame]] for A is properly set up before jumping to the tail-called subroutine. For instance, on [[computing platform|platform]]s where the [[call stack]] does not just contain the [[return statement|return address]], but also the parameters for the subroutine, the compiler may need to emit instructions to adjust the call stack. On such a platform, for the code:&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;function&#039;&#039;&#039; foo(data1, data2)&lt;br /&gt;
    B(data1)&lt;br /&gt;
    &#039;&#039;&#039;return&#039;&#039;&#039; A(data2)&lt;br /&gt;
&lt;br /&gt;
(where &amp;lt;code&amp;gt;data1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;data2&amp;lt;/code&amp;gt; are parameters) a compiler might translate that as:{{efn| The &amp;lt;code&amp;gt;call&amp;lt;/code&amp;gt; instruction first pushes the current code location onto the stack and then performs an unconditional jump to the code location indicated by the label. The &amp;lt;code&amp;gt;ret&amp;lt;/code&amp;gt; instruction first pops a code location off the stack, then performs an unconditional jump to the retrieved code location. }}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nasm&amp;quot; line&amp;gt;&lt;br /&gt;
 foo:&lt;br /&gt;
   mov  reg,[sp+data1] ; fetch data1 from stack (sp) parameter into a scratch register.&lt;br /&gt;
   push reg            ; put data1 on stack where B expects it&lt;br /&gt;
   call B              ; B uses data1&lt;br /&gt;
   pop                 ; remove data1 from stack&lt;br /&gt;
   mov  reg,[sp+data2] ; fetch data2 from stack (sp) parameter into a scratch register.&lt;br /&gt;
   push reg            ; put data2 on stack where A expects it&lt;br /&gt;
   call A              ; A uses data2&lt;br /&gt;
   pop                 ; remove data2 from stack.&lt;br /&gt;
   ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A tail-call optimizer could then change the code to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;nasm&amp;quot; line&amp;gt;&lt;br /&gt;
 foo:&lt;br /&gt;
   mov  reg,[sp+data1] ; fetch data1 from stack (sp) parameter into a scratch register.&lt;br /&gt;
   push reg            ; put data1 on stack where B expects it&lt;br /&gt;
   call B              ; B uses data1&lt;br /&gt;
   pop                 ; remove data1 from stack&lt;br /&gt;
   mov  reg,[sp+data2] ; fetch data2 from stack (sp) parameter into a scratch register.&lt;br /&gt;
   mov  [sp+data1],reg ; put data2 where A expects it&lt;br /&gt;
   jmp  A              ; A uses data2 and returns immediately to caller.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is more efficient both in terms of execution speed and use of stack space.&lt;br /&gt;
&lt;br /&gt;
===Through trampolining===&lt;br /&gt;
Since many [[Scheme (programming language)|Scheme]] compilers use [[C (programming language)|C]] as an intermediate target code, the tail recursion must be encoded in C without growing the stack, even if the C compiler does not optimize tail calls. Many implementations achieve this by using a device known as a [[Trampoline (computers)|trampoline]], a piece of code that repeatedly calls functions. All functions are entered via the trampoline. When a function has to tail-call another, instead of calling it directly and then returning the result, it returns the address of the function to be called and the call parameters back to the trampoline (from which it was called itself), and the trampoline takes care of calling this function next with the specified parameters. This ensures that the C stack does not grow and iteration can continue indefinitely.&lt;br /&gt;
&lt;br /&gt;
It is possible to implement trampolines using [[higher-order function]]s in languages that support them, such as [[Groovy (programming language)|Groovy]], [[Visual Basic .NET]] and [[C Sharp (programming language)|C#]].&amp;lt;ref name=&amp;quot;onyourtail&amp;quot;&amp;gt;Samuel Jack, [http://blog.functionalfun.net/2008/04/bouncing-on-your-tail.html Bouncing on your tail]. &#039;&#039;Functional Fun&#039;&#039;. April 9, 2008.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using a trampoline for all function calls is rather more expensive than the normal C function call, so at least one Scheme compiler, [[Chicken (Scheme implementation)|Chicken]], uses a technique first described by [[Henry Baker (computer scientist)|Henry Baker]] from an unpublished suggestion by [[Andrew Appel]],&amp;lt;ref name=&amp;quot;Chicken&amp;quot;&amp;gt;Henry Baker, [http://home.pipeline.com/~hbaker1/CheneyMTA.html &amp;quot;CONS Should Not CONS Its Arguments, Part II: Cheney on the M.T.A.&amp;quot;] {{Webarchive|url=https://web.archive.org/web/20060303155622/http://home.pipeline.com/~hbaker1/CheneyMTA.html |date=2006-03-03 }}&amp;lt;/ref&amp;gt; in which normal C&amp;amp;nbsp;calls are used but the stack size is checked before every call. When the stack reaches its maximum permitted size, objects on the stack are [[garbage collection (computer science)|garbage-collected]] using the [[Cheney algorithm]] by moving all live data into a separate heap. Following this, the stack is unwound (&amp;quot;popped&amp;quot;) and the program resumes from the state saved just before the garbage collection. Baker says &amp;quot;Appel&#039;s method avoids making a large number of small trampoline bounces by occasionally jumping off the Empire State Building.&amp;quot;&amp;lt;ref name=&amp;quot;Chicken&amp;quot; /&amp;gt; The garbage collection ensures that mutual tail recursion can continue indefinitely. However, this approach requires that no C function call ever returns, since there is no guarantee that its caller&#039;s stack frame still exists; therefore, it involves a much more dramatic internal rewriting of the program code: [[continuation-passing style]].&lt;br /&gt;
&lt;br /&gt;
==Relation to the &#039;&#039;while&#039;&#039; statement==&lt;br /&gt;
Tail recursion can be related to the [[while loop|&#039;&#039;while&#039;&#039; statement]], an explicit iteration, for instance by transforming&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;procedure&#039;&#039;&#039; foo(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;if&#039;&#039;&#039; &#039;&#039;p&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; bar(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; foo(baz(&#039;&#039;x&#039;&#039;))&lt;br /&gt;
&lt;br /&gt;
into&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;procedure&#039;&#039;&#039; foo(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;while&#039;&#039;&#039; &#039;&#039;&#039;true&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;if&#039;&#039;&#039; &#039;&#039;p&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
             &#039;&#039;&#039;return&#039;&#039;&#039; bar(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;x&#039;&#039; ← baz(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
where &#039;&#039;x&#039;&#039; may be a tuple involving more than one variable: if so, care must be taken in implementing the [[Assignment (computer science)|assignment statement]] &#039;&#039;x&#039;&#039; ← baz(&#039;&#039;x&#039;&#039;) so that dependencies are respected. One may need to introduce auxiliary variables or use a &#039;&#039;[[Swap (computer science)|swap]]&#039;&#039; construct.&lt;br /&gt;
&lt;br /&gt;
More generally,&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;procedure&#039;&#039;&#039; foo(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;if&#039;&#039;&#039; &#039;&#039;p&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; bar(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;else if&#039;&#039;&#039; &#039;&#039;q&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; baz(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     ...&lt;br /&gt;
     &#039;&#039;&#039;else if&#039;&#039;&#039; &#039;&#039;r&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; foo(qux(&#039;&#039;x&#039;&#039;))&lt;br /&gt;
     ...&lt;br /&gt;
     &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return&#039;&#039;&#039; foo(quux(&#039;&#039;x&#039;&#039;))&lt;br /&gt;
&lt;br /&gt;
can be transformed into&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;procedure&#039;&#039;&#039; foo(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
     &#039;&#039;&#039;while&#039;&#039;&#039; &#039;&#039;&#039;true&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;if&#039;&#039;&#039; &#039;&#039;p&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
             &#039;&#039;&#039;return&#039;&#039;&#039; bar(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         &#039;&#039;&#039;else if&#039;&#039;&#039; &#039;&#039;q&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
             &#039;&#039;&#039;return&#039;&#039;&#039; baz(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         ...&lt;br /&gt;
         &#039;&#039;&#039;else if&#039;&#039;&#039; &#039;&#039;r&#039;&#039;(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
             &#039;&#039;x&#039;&#039; ← qux(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
         ...&lt;br /&gt;
         &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;x&#039;&#039; ← quux(&#039;&#039;x&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
For instance, this [[Julia (programming language)|Julia]] program gives a non-tail recursive definition &amp;lt;code&amp;gt;fact&amp;lt;/code&amp;gt; of the factorial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;julia&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
function factorial(n)&lt;br /&gt;
    if n == 0&lt;br /&gt;
        return 1&lt;br /&gt;
    else&lt;br /&gt;
        return n * factorial(n - 1)&lt;br /&gt;
    end&lt;br /&gt;
end &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Indeed, &amp;lt;code&amp;gt;n * factorial(n - 1)&amp;lt;/code&amp;gt; wraps the call to &amp;lt;code&amp;gt;factorial&amp;lt;/code&amp;gt;. But it can be transformed into a tail-recursive definition by adding an argument &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; called an &#039;&#039;accumulator&#039;&#039;.&amp;lt;ref name=&amp;quot;sicp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Julia program gives a tail-recursive definition &amp;lt;code&amp;gt;fact_iter&amp;lt;/code&amp;gt; of the factorial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;julia&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
function factorial(n::Integer, a::Integer)&lt;br /&gt;
    if n == 0:&lt;br /&gt;
        return a&lt;br /&gt;
    else&lt;br /&gt;
        return factorial(n - 1, n * a)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function factorial(n::Integer)&lt;br /&gt;
    return factorial(n, 1)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This Julia program gives an iterative definition &amp;lt;code&amp;gt;fact_iter&amp;lt;/code&amp;gt; of the factorial:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;julia&amp;quot;&amp;gt;&lt;br /&gt;
function fact_iter(n::Integer, a::Integer)&lt;br /&gt;
    while n &amp;gt; 0&lt;br /&gt;
        a = n * a&lt;br /&gt;
        n = n - 1&lt;br /&gt;
    end&lt;br /&gt;
    return a&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function factorial(n::Integer)&lt;br /&gt;
    return fact_iter(n, one(n))&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Language support==&lt;br /&gt;
* [[C++ (programming language)|C++]] {{En dash}} C and C++ both do tail-call optimization.&amp;lt;ref&amp;gt;{{cite web|url=https://stackoverflow.com/questions/34125/which-if-any-c-compilers-do-tail-recursion-optimization|title=Which, if any, C++ compilers do tail-recursion optimization?|website=stackoverflow}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Clojure (programming language)|Clojure]] {{En dash}} Clojure has &amp;lt;code&amp;gt;recur&amp;lt;/code&amp;gt; special form.&amp;lt;ref&amp;gt;{{cite web|url=https://clojure.org/reference/special_forms#recur|title=(recur expr*)|website=clojure.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Common Lisp]] {{En dash}} Some implementations perform tail-call optimization during compilation if optimizing for speed&lt;br /&gt;
* [[Elixir (programming language)|Elixir]] {{En dash}} Elixir implements tail-call optimization,&amp;lt;ref&amp;gt;{{cite web|url=http://elixir-lang.org/getting-started/recursion.html|title=Recursion|website=elixir-lang.github.com}}&amp;lt;/ref&amp;gt;as do all languages currently targeting the BEAM VM.&lt;br /&gt;
* [[Elm (programming language)|Elm]] {{En dash}} Yes&amp;lt;ref&amp;gt;{{ cite web|url=https://functional-programming-in-elm.netlify.app/recursion/tail-call-elimination.html|title=Functional Programming in Elm: Tail-Call Elimination|first=Evan|last=Czaplicki}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Erlang (programming language)|Erlang]] {{En dash}} Yes&lt;br /&gt;
* [[F Sharp (programming language)|F#]] {{En dash}} F# implements TCO by default where possible &amp;lt;ref&amp;gt;{{cite web|url=https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/|title=Tail Calls in F#|website=msdn|date=8 July 2011 |publisher=Microsoft}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Go (programming language)|Go]] {{En dash}} No support&amp;lt;ref&amp;gt;{{cite web|url=https://github.com/golang/go/issues/22624|title=proposal: Go 2: add become statement to support tail calls|website=github.com}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Haskell (programming language)|Haskell]] {{En dash}} Yes&amp;lt;ref&amp;gt;{{Cite web|url=https://wiki.haskell.org/Tail_recursion|title=Tail recursion - HaskellWiki|website=wiki.haskell.org|access-date=2019-06-08}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[JavaScript]] {{En dash}} [[ECMAScript]] 6.0 compliant engines should have tail calls&amp;lt;ref&amp;gt;{{cite web|url=http://bdadam.com/blog/video-douglas-crockford-about-the-new-good-parts.html|title=Worth watching: Douglas Crockford speaking about the good new parts of JavaScript in 2014|first=Adam|last=Beres-Deak|website=bdadam.com}}&amp;lt;/ref&amp;gt; which is now implemented on [[Safari (browser)|Safari]]/[[WebKit]]&amp;lt;ref&amp;gt;{{cite web|url=https://www.webkit.org/blog/4054/es6-in-webkit/|title=ECMAScript 6 in WebKit| date=13 October 2015}}&amp;lt;/ref&amp;gt; but rejected by V8 and SpiderMonkey&lt;br /&gt;
* [[Kotlin (programming language)|Kotlin]] {{En dash}} Has &amp;lt;code&amp;gt;tailrec&amp;lt;/code&amp;gt; modifier for functions&amp;lt;ref&amp;gt;{{cite web| url=https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions|title=Functions: infix, vararg, tailrec - Kotlin Programming Language|website=Kotlin}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Lua (programming language)|Lua]] {{En dash}} Tail recursion is required by the language definition&amp;lt;ref&amp;gt;{{cite web| url=https://www.lua.org/manual/5.3/manual.html#3.4.10|title=Lua 5.3 Reference Manual|website=www.lua.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Objective-C]] {{En dash}} Compiler optimizes tail calls when -O1 (or higher) option specified, but it is easily disturbed by calls added by [[Automatic Reference Counting]] (ARC).&lt;br /&gt;
* [[OCaml]] {{En dash}} Yes&lt;br /&gt;
* [[Perl (programming language)|Perl]] {{En dash}} Explicit with a variant of the &amp;quot;goto&amp;quot; statement that takes a function name: &amp;lt;code&amp;gt;goto &amp;amp;NAME;&amp;lt;/code&amp;gt;&amp;lt;ref&amp;gt;{{cite web|url=http://perldoc.perl.org/functions/goto.html|title=goto - perldoc.perl.org| website=perldoc.perl.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Prolog|Prolog]]  {{En dash}} [[SWI-Prolog]] implements tail-recursion optimization.&amp;lt;ref&amp;gt;{{cite web|url=https://www.lix.polytechnique.fr/~catuscia/teaching/prolog/Manual/sec-2.10.html | title=SWI-Prolog Reference Manual | website=www.lix.polytechnique.fr}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[PureScript]] {{En dash}} Yes&lt;br /&gt;
* [[Python (programming language)|Python]] {{En dash}} Stock Python implementations do not perform tail-call optimization, though a third-party module is available to do this.&amp;lt;ref&amp;gt;{{cite web|url=https://github.com/baruchel/tco|title=baruchel/tco|website=GitHub|date=29 March 2022}}&amp;lt;/ref&amp;gt; Language inventor [[Guido van Rossum]] contended that [[stack traces]] are altered by tail-call elimination making debugging harder, and preferred that programmers use explicit [[iteration]] instead.&amp;lt;ref&amp;gt;{{cite web|url=http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html|title=Neopythonic: Tail Recursion Elimination|first=Guido Van|last=Rossum|date=22 April 2009}}&amp;lt;/ref&amp;gt; In Python 3.14, a new interpreter was introduced that uses tail-call based dispatch of Python opcodes.&amp;lt;ref name=&amp;quot;Python Tail-Call Interpreter Dev Discussion&amp;quot;&amp;gt;{{cite web |date=2024-01-08 |title=Tail-calling interpreter |url=https://github.com/faster-cpython/ideas/issues/642 |access-date=2025-03-08 |website=GitHub}}&amp;lt;/ref&amp;gt; This resulted in overall improved performance when compared to Python 3.13.&amp;lt;ref&amp;gt;{{Cite web |title=What&#039;s new in Python 3.14 |url=https://docs.python.org/3.14/whatsnew/3.14.html#a-new-type-of-interpreter |access-date=2025-02-19 |website=Python documentation |language=en}}&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;Python Tail-Calling Interpreter Proposal&amp;quot;&amp;gt;{{cite web |date=2025-01-06 |title=A new tail-calling interpreter for significantly better interpreter performance |url=https://github.com/python/cpython/issues/128563 |access-date=2025-03-08 |website=GitHub}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[R (programming language)|R]] {{En dash}} Yes, {{Code|tailcall()}} function introduced in R.4.4.0&amp;lt;ref&amp;gt;{{Cite web |date=2024-04-25 |title=What&#039;s new in R 4.4.0? |url=https://www.jumpingrivers.com/blog/whats-new-r44/ |access-date=2024-04-28 |website=www.jumpingrivers.com |language=en-gb}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Racket (programming language)|Racket]] {{En dash}} Yes&amp;lt;ref&amp;gt;{{cite web|url=https://docs.racket-lang.org/reference/eval-model.html#(part._.Tail_.Position)|title=The Racket Reference|website=docs.racket-lang.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Ruby (programming language)|Ruby]] {{En dash}} Yes, but disabled by default &amp;lt;ref&amp;gt;{{cite web|url=https://docs.ruby-lang.org/en/master/RubyVM/InstructionSequence.html#method-c-compile_option-3D|title=Ruby Tail Call Optimisation}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Rust (programming language)|Rust]] {{En dash}} tail-call optimization may be done in limited circumstances, but is not guaranteed&amp;lt;ref&amp;gt;{{cite web|url=https://prev.rust-lang.org/en-US/faq.html#does-rust-do-tail-call-optimization|title=Rust FAQ|website=prev.rust-lang.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Scala (programming language)|Scala]] {{En dash}} Tail-recursive functions are automatically optimized by the compiler. Such functions can also optionally be marked with a &amp;lt;code&amp;gt;@tailrec&amp;lt;/code&amp;gt; annotation, which makes it a compilation error if the function is not tail recursive&amp;lt;ref&amp;gt;{{Cite web|url=https://www.scala-lang.org/api/2.13.0/scala/annotation/tailrec.html|title=Scala Standard Library 2.13.0 - scala.annotation.tailrec|website=www.scala-lang.org|access-date=2019-06-20}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Scheme (programming language)|Scheme]] {{En dash}} Required by the language definition&amp;lt;ref&amp;gt;{{cite web|url=http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-6.html#%25_sec_3.5|title=Revised^5 Report on the Algorithmic Language Scheme| website=www.schemers.org}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web|url=http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-8.html#node_sec_5.11| title=Revised [6] Report on the Algorithmic Language Scheme|website=www.r6rs.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Swift_(programming_language)|Swift]] {{En dash}} In some cases (as of 2014).&amp;lt;ref&amp;gt;{{cite web |title=Does Swift implement tail call optimization? |url=https://stackoverflow.com/questions/24023580/does-swift-implement-tail-call-optimization-and-in-mutual-recursion-case |access-date=13 March 2024 |date=2014}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Tcl]] {{En dash}} Since Tcl 8.6, Tcl has a {{Code|tailcall}} command&amp;lt;ref&amp;gt;{{cite web|url=http://www.tcl.tk/man/tcl/TclCmd/tailcall.htm| title=tailcall manual page - Tcl Built-In Commands|website=www.tcl.tk}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Zig (programming language)|Zig]] {{En dash}} Yes&amp;lt;ref&amp;gt;{{cite web | url=https://ziglang.org/documentation/master/#call | title=Documentation - the Zig Programming Language }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
{{Portal|Computer programming}}&lt;br /&gt;
{{Wiktionary|tail recursion}}&lt;br /&gt;
* [[Course-of-values recursion]]&lt;br /&gt;
* [[Recursion (computer science)]]&lt;br /&gt;
* [[Primitive recursive function]]&lt;br /&gt;
* [[Inline expansion]]&lt;br /&gt;
* [[Leaf subroutine]]&lt;br /&gt;
* [[Corecursion]]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
{{Notelist}}&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Tail Call}}&lt;br /&gt;
[[Category:Programming language implementation]]&lt;br /&gt;
[[Category:Implementation of functional programming languages]]&lt;br /&gt;
[[Category:Subroutines]]&lt;br /&gt;
[[Category:Control flow]]&lt;br /&gt;
[[Category:Recursion]]&lt;br /&gt;
[[Category:Scheme (programming language)]]&lt;br /&gt;
[[Category:Articles with example C code]]&lt;br /&gt;
[[Category:Articles with example Scheme (programming language) code]]&lt;br /&gt;
[[pt:Recursividade (ciência da computação)#Funções recursivas em cauda]]&lt;br /&gt;
[[es:Recursión (ciencias de computación)#Funciones de recursión de cola]]&lt;/div&gt;</summary>
		<author><name>2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF</name></author>
	</entry>
	<entry>
		<id>https://wiki.sarg.dev/index.php?title=Stack_trace&amp;diff=393251</id>
		<title>Stack trace</title>
		<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php?title=Stack_trace&amp;diff=393251"/>
		<updated>2025-10-19T15:53:24Z</updated>

		<summary type="html">&lt;p&gt;2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF: /* Java */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Short description|Report of stack frames during program execution}}&lt;br /&gt;
{{Redirect|Backtrace|the 2018 film|Backtrace (film)}}&lt;br /&gt;
&lt;br /&gt;
In [[computing]], a &#039;&#039;&#039;stack trace&#039;&#039;&#039; (also called &#039;&#039;&#039;stack backtrace&#039;&#039;&#039;&amp;lt;ref&amp;gt;{{cite web | url=https://www.gnu.org/software/libc/manual/html_node/Backtraces.html | title=libc manual: backtraces | publisher=gnu.org | accessdate=8 July 2014}}&amp;lt;/ref&amp;gt; or &#039;&#039;&#039;stack traceback&#039;&#039;&#039;&amp;lt;ref&amp;gt;{{cite web | url=https://docs.python.org/3/library/traceback.html | title=traceback — Print or retrieve a stack traceback | publisher=python.org | accessdate=8 July 2014}}&amp;lt;/ref&amp;gt;) is a report of the active [[stack frame]]s at a certain point in time during the execution of a [[computer program|program]]. When a program is run, memory is often dynamically allocated in two places: the [[Stack (abstract data type)#Hardware stack|stack]] and the [[Memory_management#HEAP|heap]]. Memory is continuously allocated on a stack but not on a heap. Stack also refers to a programming construct, thus to differentiate it, this stack is referred to as the program&#039;s &#039;&#039;&#039;[[Call stack|function call stack]]&#039;&#039;&#039;. Technically, once a block of memory has been allocated on the stack, it cannot be easily removed as there can be other blocks of memory that were allocated after it. Each time a function is called in a program, a block of memory called an &#039;&#039;&#039;activation record&#039;&#039;&#039; is allocated on top of the call stack. Generally, the activation record stores the function&#039;s arguments and local variables. What exactly it contains and how it&#039;s laid out is determined by the [[calling convention]].&lt;br /&gt;
&lt;br /&gt;
Programmers commonly use stack tracing during interactive and post-mortem [[debugging]]. End-users may see a stack trace displayed as part of an [[error message]], which the user can then report to a programmer.&lt;br /&gt;
&lt;br /&gt;
A stack trace allows tracking the sequence of [[nested function]]s called - up to the point where the stack trace is generated. In a post-mortem scenario this extends up to the function where the failure occurred (but was not necessarily caused). [[Tail call|Sibling calls]] do not appear in a stack trace.&lt;br /&gt;
&lt;br /&gt;
== Language support ==&lt;br /&gt;
Many programming languages, including [[Java (programming language)|Java]]&amp;lt;ref&amp;gt;{{cite web | title=Thread (Java SE 16 &amp;amp; JDK 16) | website=Java Platform Standard Edition &amp;amp; Java Development Kit Version 16 API Specification | date=2021-03-04 | url=https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Thread.html#getStackTrace() | access-date=2021-07-04}}&amp;lt;/ref&amp;gt; and [[C Sharp (programming language)|C#]],&amp;lt;ref&amp;gt;{{cite web | title=Environment.StackTrace Property (System) | website=Microsoft Docs | date=2021-05-07 | url=https://docs.microsoft.com/en-us/dotnet/api/system.environment.stacktrace | access-date=2021-07-04}}&amp;lt;/ref&amp;gt; have built-in support for retrieving the current stack trace via system calls. Before &amp;lt;code&amp;gt;std::stacktrace&amp;lt;/code&amp;gt; was added in standard library as a container for &amp;lt;code&amp;gt;std::stacktrace_entry&amp;lt;/code&amp;gt;, pre-[[C++23]] has no built-in support for doing this, but C++ users can retrieve stack traces with (for example) the [https://stacktrace.sourceforge.net/ stacktrace] [[library (computing)|library]]. In [[JavaScript]], [[Exception handling|exceptions]] hold a &amp;lt;code&amp;gt;stack&amp;lt;/code&amp;gt; property that contain the stack from the place where it was thrown.&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
As an example, the following [[Python (programming language)|Python]] program contains an error.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot; highlight=&amp;quot;3,9,13,16&amp;quot;&amp;gt;&lt;br /&gt;
def a() -&amp;gt; int:&lt;br /&gt;
    i: int = 0&lt;br /&gt;
    j: int = b(i)&lt;br /&gt;
    return j&lt;br /&gt;
&lt;br /&gt;
def b(z: int) -&amp;gt; int:&lt;br /&gt;
    k: int = 5&lt;br /&gt;
    if z == 0:&lt;br /&gt;
        c()&lt;br /&gt;
    return k + z&lt;br /&gt;
&lt;br /&gt;
def c() -&amp;gt; None:&lt;br /&gt;
    error()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    a()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Running the program under the standard Python interpreter produces the following error message.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;pytb&amp;quot;&amp;gt;&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;file.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;&lt;br /&gt;
    a()&lt;br /&gt;
  File &amp;quot;file.py&amp;quot;, line 3, in a&lt;br /&gt;
    j = b(i)&lt;br /&gt;
  File &amp;quot;file.py&amp;quot;, line 9, in b&lt;br /&gt;
    c()&lt;br /&gt;
  File &amp;quot;file.py&amp;quot;, line 13, in c&lt;br /&gt;
    error()&lt;br /&gt;
NameError: name &#039;error&#039; is not defined&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The stack trace shows where the error occurs, namely in the &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; function. It also shows that the &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; function was called by &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt;, which was called by &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, which was in turn called by the code on line 15 (the last line) of the program. The activation records for each of these three functions would be arranged in a stack such that the &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; function would occupy the bottom of the stack and the &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt; function would occupy the top of the stack.&lt;br /&gt;
&lt;br /&gt;
=== Java ===&lt;br /&gt;
In [[Java (programming language)|Java]], stack traces can be dumped manually with &amp;lt;code&amp;gt;Thread.dumpStack()&amp;lt;/code&amp;gt;&amp;lt;ref&amp;gt;{{Cite web|title=Thread (Java Platform SE 8 )|url=https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#dumpStack--|access-date=2021-06-15|website=docs.oracle.com}}&amp;lt;/ref&amp;gt; Take the following input:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line=&amp;quot;1&amp;quot; highlight=&amp;quot;3,7,11,19&amp;quot;&amp;gt;&lt;br /&gt;
public class Main {&lt;br /&gt;
    static void demo() {&lt;br /&gt;
        demo1();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    static void demo1() {&lt;br /&gt;
        demo2();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    static void demo2() {&lt;br /&gt;
        demo3();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    static void demo3() {&lt;br /&gt;
        Thread.dumpStack();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(String args[]) {&lt;br /&gt;
        demo();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exception lists functions in descending order, so the most-inner call is first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
java.lang.Exception: Stack trace&lt;br /&gt;
        at java.lang.Thread.dumpStack(Thread.java:1336)&lt;br /&gt;
        at Main.demo3(Main.java:15)&lt;br /&gt;
        at Main.demo2(Main.java:11)&lt;br /&gt;
        at Main.demo1(Main.java:7)&lt;br /&gt;
        at Main.demo(Main.java:3)&lt;br /&gt;
        at Main.main(Main.java:19)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== C and C++ ===&lt;br /&gt;
Both [[C (programming language)|C]] and [[C++]] (pre-[[C++23]]) do not have native support for obtaining stack traces, but libraries such as [[GNU C Library|glibc]] and [[Boost (C++ libraries)|boost]] provide this functionality.&amp;lt;ref name=&amp;quot;glibc Backtraces&amp;quot;&amp;gt;{{Cite web|title=Backtraces (The GNU C Library)|url=https://www.gnu.org/software/libc/manual/html_node/Backtraces.html|access-date=2021-06-15|website=www.gnu.org}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{Cite web|title=Getting Started - 1.76.0|url=https://www.boost.org/doc/libs/1_76_0/doc/html/stacktrace/getting_started.html|access-date=2021-06-15|website=www.boost.org}}&amp;lt;/ref&amp;gt; In these languages, some compiler optimizations may interfere with the call stack information that can be recovered at runtime. For instance, [[Inline expansion|inlining]] can cause missing stack frames, [[tail call]] optimizations can replace one stack frame with another, and frame pointer elimination can prevent call stack analysis tools from correctly interpreting the contents of the call stack.&amp;lt;ref name=&amp;quot;glibc Backtraces&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, glibc&#039;s &amp;lt;code&amp;gt;backtrace()&amp;lt;/code&amp;gt; function returns an output with the program function and memory address.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
./a.out() [0x40067f]&lt;br /&gt;
./a.out() [0x4006fe]&lt;br /&gt;
./a.out() [0x40070a]&lt;br /&gt;
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7f7e60738f45]&lt;br /&gt;
./a.out() [0x400599]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of [[C++23]], stack traces can be dumped manually by printing the value returned by static member function &amp;lt;code&amp;gt;std::stacktrace::current()&amp;lt;/code&amp;gt;:&amp;lt;ref&amp;gt;{{Cite web|date=2021-10-23|title=Working Draft, Standard for Programming Language C++|url=http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/n4901.pdf|website=open-std.org|publisher=ISO/IEC|page=766}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
import std;&lt;br /&gt;
&lt;br /&gt;
using std::stacktrace;&lt;br /&gt;
&lt;br /&gt;
void bar() {&lt;br /&gt;
    std::println(&amp;quot;Stacktrace from bar():\n{}&amp;quot;, stacktrace::current());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void foo() {&lt;br /&gt;
    bar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    foo();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rust ===&lt;br /&gt;
[[Rust (programming language)|Rust]] has two types of errors. Functions that use the panic [[Macro (computer science)|macro]] are &amp;quot;unrecoverable&amp;quot; and the current thread will become poisoned experiencing stack unwinding. Functions that return a &amp;lt;code&amp;gt;std::result::Result&amp;lt;/code&amp;gt; are &amp;quot;recoverable&amp;quot; and can be handled gracefully.&amp;lt;ref&amp;gt;{{Cite web|title=rustonomicon unwinding - Rust|url=https://doc.rust-lang.org/nomicon/unwinding.html#:~:text=Rust%20has%20a%20tiered%20error,be%20handled%2C%20the%20thread%20panics.|website=doc.rust-lang.org}}&amp;lt;/ref&amp;gt; However, recoverable errors cannot generate a stack trace as they are manually added and not a result of a runtime error.&lt;br /&gt;
&lt;br /&gt;
As of June 2021, [[Rust (programming language)|Rust]] has experimental support for stack traces on unrecoverable errors. Rust supports printing to [[stderr]] when a thread panics, but it must be enabled by setting the &amp;lt;code&amp;gt;RUST_BACKTRACE&amp;lt;/code&amp;gt; [[environment variable]].&amp;lt;ref&amp;gt;{{Cite web|title=std::backtrace - Rust|url=https://doc.rust-lang.org/std/backtrace/index.html|access-date=2021-06-15|website=doc.rust-lang.org}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When enabled, such backtraces look similar to below, with the most recent call first.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
thread &#039;main&#039; panicked at &#039;execute_to_panic&#039;, main.rs:3&lt;br /&gt;
stack backtrace:&lt;br /&gt;
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace&lt;br /&gt;
   1: std::panicking::default_hook::{{closure}}&lt;br /&gt;
   2: std::panicking::default_hook&lt;br /&gt;
   3: std::panicking::rust_panic_with_hook&lt;br /&gt;
   4: std::panicking::begin_panic&lt;br /&gt;
   5: futures::task_impl::with&lt;br /&gt;
   6: futures::task_impl::park&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Tail call]]&lt;br /&gt;
* [[Context (computing)]]&lt;br /&gt;
* [[Stack overflow]]&lt;br /&gt;
* [[Exception handling]]&lt;br /&gt;
* [[Call stack]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Stack Trace}}&lt;br /&gt;
[[Category:Debugging]]&lt;br /&gt;
[[Category:Articles with example Python (programming language) code]]&lt;/div&gt;</summary>
		<author><name>2605:8D80:6C24:88A9:E0B2:AD7C:76A8:4BDF</name></author>
	</entry>
</feed>