Fact-checked by Grok 2 weeks ago

Mutual recursion

Mutual recursion is a form of in which two or more functions invoke each other recursively, creating a of interdependent calls that collectively solve a problem by breaking it into subproblems handled by the cooperating functions. This approach extends direct recursion, where a function calls itself, to scenarios requiring multiple perspectives or states, such as distinguishing between odd and even positions in or traversing hierarchical structures like file systems. In languages like (using the and keyword) and (using letrec), mutual recursion is explicitly supported through dedicated syntax allowing definitions to be declared together for mutual reference. It is particularly useful for modeling problems with multiple interrelated components, such as computing Fibonacci-like sequences via separate trackers for immature and mature states, or analyzing parity in sequences through alternating even and odd checkers. While it can introduce complexity in termination analysis due to the cyclic dependencies, proper base cases ensure convergence, and studies show it can simplify algorithm design and proofs compared to equivalent direct recursive solutions in certain combinatorial tasks.

Definition and Fundamentals

Formal Definition

Mutual recursion refers to a scenario in where a set of two or more are defined such that each invokes at least one other within the set, thereby creating a in the directed of the functions. This cyclic distinguishes mutual recursion from simpler forms, as the execution path can alternate between the functions until termination conditions are met. Formally, for a pair of functions f and g, mutual recursion arises when the body of f contains a recursive call to g, and the body of g contains a recursive call to f, with base cases incorporated to guarantee halting. More generally, for a set of n \geq 2 functions \{f_1, f_2, \dots, f_n\}, mutual recursion holds if the of the induced by these functions is strongly connected, meaning there is a directed path from each f_i to every other f_j (where i \neq j) via the recursive calls. The mutual dependency formed by these recursive calls represents a in the call , where every function is reachable from every other via directed paths of calls. To avoid infinite loops, each function must include termination conditions—typically base cases that halt when certain criteria (e.g., input size zero or a predefined ) are satisfied—ensuring the recursion depth is finite. A basic pseudocode template for two mutually recursive functions illustrates this structure:
function f(x):
    if base_case_f(x):
        return value_f  // termination condition for f
    else:
        return g(process(x))  // call to g

function g(y):
    if base_case_g(y):
        return value_g  // termination condition for g
    else:
        return f(process(y))  // call to f
In this template, process denotes some transformation of the input, and the base cases ensure eventual termination.

Distinction from Other Recursion Types

Mutual recursion is distinguished from direct recursion, in which a single explicitly calls itself within its own definition, forming a straightforward self-referential . In direct recursion, the call graph manifests as a self-loop on a single node, resulting in a linear sequence of call frames accumulating on the during execution. This simplicity contrasts with mutual recursion's involvement of multiple functions, where the dependencies create a more intricate pattern of invocations. Unlike general indirect —where a invokes another that, through a possibly longer chain, eventually leads back to the original without necessarily forming a tight pairwise —mutual recursion specifically entails symmetric or cyclic dependencies among two or more distinct , often in a direct back-and-forth manner. For instance, indirect recursion might involve a sequence of three or more (A calls B, B calls C, C calls A), broadening the scope beyond the paired interdependencies characteristic of mutual recursion. The call in indirect recursion can appear tree-like if branching occurs from intermediate calls, whereas mutual recursion's features explicit cycles between the participating , such as alternating edges between two nodes. These structural differences in mutual recursion introduce greater complexity in managing call stacks, as the interleaving of frames from multiple functions can lead to deeper stack depths compared to the uniform self-calls in direct recursion. Consequently, mutual recursion heightens the risk of stack overflow errors, particularly in environments with limited stack space, due to the sustained accumulation of diverse activation records across the cycle without the simplifying uniformity of single-function recursion. This added intricacy necessitates careful base case design to prevent unbounded cycling and ensure termination.

Illustrative Examples

Programming Implementations

Mutual recursion is frequently demonstrated through a pair of functions that determine whether a non-negative integer is even or odd by invoking each other, providing a simple yet illustrative case of interdependence. In this setup, the is_even function checks if the input is zero (a base case returning true) or otherwise delegates to is_odd on the decremented value; conversely, is_odd returns false for zero and calls is_even on the decremented input. This mutual calling chain alternates until reaching the base case, ensuring correct parity classification. The following Python implementation exemplifies this:
python
def is_even(n):
    if n == 0:
        return True
    return is_odd(n - 1)

def is_odd(n):
    if n == 0:
        return False
    return is_even(n - 1)
For instance, is_even(4) proceeds as: even(4) → odd(3) → even(2) → odd(1) → even(0) → true, propagating back to true; similarly, is_odd(3) yields true. This example highlights how mutual recursion mirrors the logical interdependence of even and odd numbers, where each property relies on the of the other. An advanced application appears in compiler design, where recursive descent parsers for context-free s use mutually recursive procedures to handle non-terminals like expressions and terms in arithmetic languages. Each parsing function corresponds to a grammar production and calls others to process substructures, such as descending into factors within terms or expressions within parenthesized factors. This approach naturally accommodates left-recursive or nested rules without additional machinery, provided the grammar is LL(1). A simplified Python snippet for parsing basic arithmetic expressions (grammar: expr → term {+ term}; term → factor { factor}*; factor → number | (expr)) illustrates this:
python
tokens = []  # Assume global list of tokenized input, e.g., ['2', '+', '3', '*', '4']
pos = 0      # Global position in tokens

def parse_expr():
    result = parse_term()
    while pos < len(tokens) and tokens[pos] == '+':
        pos += 1
        result += parse_term()
    return result

def parse_term():
    result = parse_factor()
    while pos < len(tokens) and tokens[pos] == '*':
        pos += 1
        result *= parse_factor()
    return result

def parse_factor():
    global pos
    if tokens[pos].isdigit():
        num = int(tokens[pos])
        pos += 1
        return num
    elif tokens[pos] == '(':
        pos += 1  # Consume '('
        result = parse_expr()
        pos += 1  # Consume ')'
        return result
    raise ValueError("Invalid factor")
Executing parse_expr() on for "2 + 3 * 4" yields 14, with calls chaining: expr → term → factor (2) → term → factor (3) → factor (4 via *), demonstrating mutual invocation for nested . Base cases handle terminals like numbers or parentheses to halt . In mutual recursion, the call accumulates from the interleaved calls, with depth scaling linearly to the 's nesting level, akin to direct ; for the even-odd example, the maximum depth equals the input value, while parsers depth-match expression complexity. Termination is guaranteed by base cases that detect trivial inputs (e.g., zero or terminals) and avoid further calls, progressing toward these without cycles in well-formed inputs. Omitting base cases in mutual recursion triggers infinite alternation between functions, exhausting stack and causing errors, as seen if is_even and is_odd lack zero checks, leading to unending decrements.

Mathematical Formulations

Mutual recursion manifests in through interdependent recursive definitions, where multiple functions or relations are specified simultaneously, each referring to the others, often to model sequences in or inductive structures in . These formulations ensure well-definedness via well-founded orders, such as the natural numbers, guaranteeing for functions. Unlike direct recursion, which involves a single invoking itself, mutual recursion requires coordinated definitions across functions to avoid circularity without progress. A prominent example arises in variants of the , which can be adapted to incorporate mutual recursion between functions representing successive hyperoperations, such as , , and , where higher-level operations recursively invoke lower ones in an interdependent to demonstrate growth beyond primitive recursion. Fibonacci-like sequences provide a concrete illustration of mutual recursion, as seen in the classic rabbit population model, where the numbers of adult and immature rabbits in successive months are defined interdependently. Let A_i denote the number of adult rabbit pairs in month i, and B_i the number of immature pairs. The recursive equations are: \begin{align*} A_i &= \begin{cases} 0 & \text{if } i = 1, \\ A_{i-1} + B_{i-1} & \text{if } i \geq 2, \end{cases} \\ B_i &= \begin{cases} 1 & \text{if } i = 1, \\ A_{i-1} & \text{if } i \geq 2. \end{cases} \end{align*} The total population T_i = A_i + B_i yields the Fibonacci sequence shifted by one, with T_i = F_i where F_1 = 1, F_2 = 1. This mutual dependence captures the biological process: adults produce immatures, and immatures mature into adults. Another pair of mutually recursive functions illustrates linear growth patterns in sequences. Define f: \mathbb{N} \to \mathbb{N} and g: \mathbb{N} \to \mathbb{N} by the equations \begin{align*} f(n) &= \begin{cases} 0 & \text{if } n = 0, \\ g(n-1) + 1 & \text{if } n \geq 1, \end{cases} \\ g(n) &= \begin{cases} 1 & \text{if } n = 0, \\ f(n-1) \times 2 & \text{if } n \geq 1. \end{cases} \end{align*} Computing initial terms reveals an alternating pattern: f(0) = 0, g(0) = 1, g(1) = 0 \times 2 = 0, f(1) = 1 + 1 = 2, g(2) = 2 \times 2 = 4, f(2) = 0 + 1 = 1, and so on, producing well-defined values for all natural numbers n. Such definitions are common in analyzing interdependent sequences in number theory. The of these mutual recursive definitions follows from their well-founded nature on the natural numbers. To sketch a proof, proceed by on n: The base cases n=0 are explicitly given, establishing f(0) and g(0). Assume f(k) and g(k) are computable for all k < n; then f(n) = g(n-1) + 1 and g(n) = f(n-1) \times 2 reduce to prior terms by the induction hypothesis, yielding computable results via standard arithmetic operations. This confirms totality and , as the decreases arguments monotonically, avoiding infinite descent. In logic and , mutual recursion plays a key role in defining inductive datatypes such as . A can be formalized as the least set T satisfying T = \{\emptyset\} \cup (\{*\} \times T \times T), but for more general structures like rooted with forests of subtrees, define two mutually recursive sets: a tree t \in Tree is a pair (r, F) where r is a root label and F \in Forest is the set of its subtrees; a forest F \in Forest is a finite of Tree. This mutual definition captures the inductive hierarchy, enabling proofs of properties like finiteness or via simultaneous on both sets, foundational to structural mathematics and .

Terminology and Conceptual Variations

Standard Terminology

Mutual recursion, the core concept in this domain, refers to a programming construct where two or more functions or procedures each make recursive calls to one or more of the others, forming a cycle of dependencies that must terminate through appropriate base conditions to avoid infinite execution. This term was popularized in 1960s programming literature, particularly in discussions surrounding early recursive languages like , developed by John McCarthy, and , where simultaneous definitions of interdependent functions were introduced to enable such structures. Alternative or synonymous terms include cross-recursion, which emphasizes the bidirectional nature of calls between typically two functions, and inter-recursive functions, denoting a set of functions defined in terms of each other recursively. Essential components of mutual recursion include recursive calls, the explicit invocations from one function in the group to another, enabling the cyclic computation; base cases, conditional statements that halt the recursion by returning a value without further calls, ensuring termination; call cycle, the closed loop of function invocations that characterizes the mutual dependency; and dependency graph, a directed graph model where nodes represent functions and edges depict recursive call relationships, useful for analyzing termination and optimization. Mutual recursion can extend beyond pairwise dependencies to involve multiple functions or types in a cyclic manner, known as multi-way mutual recursion. In this form, three or more entities recursively invoke one another, forming a closed , such as A calling B, B calling C, and C calling A. This generalization is supported in dependently typed like Agda, where interleaved mutual blocks allow defining an arbitrary number of interdependent or data types simultaneously, as demonstrated by examples involving multiple parity checks or type interpretations. Tail mutual recursion occurs when the recursive calls among mutually dependent functions appear in tail position, meaning no further computation follows within each function, which facilitates tail-call optimization to prevent . For instance, in F#, mutually recursive functions like even and can be structured using let rec and and to ensure tail positioning, allowing the to optimize the into an iterative . This optimization is particularly valuable in functional languages, where mutual tail calls maintain constant during execution. In theoretical foundations like , mutual recursion relates to recursion schemes through mutual fixed points, where variadic fixed-point combinators extend Curry's to solve equations for multiple interdependent functions simultaneously. These combinators, implemented using variadic lambdas and mapping over argument lists, allow defining an arbitrary number of mutually recursive procedures without predefined , as shown in encodings for parity functions. Mutual recursion differs from in coinductive types, where constructs potentially infinite structures incrementally without termination guarantees, dual to recursion's analytic of finite data. Coinductive types, such as infinite streams, support mutual via with clauses for interdependent definitions, emphasizing productivity over termination, in contrast to mutual recursion's focus on well-founded cycles in inductive settings.

Applications and Historical Context

Prevalence in Computing

Mutual recursion emerged as a fundamental concept in early programming languages, with its introduction in in 1958 by John McCarthy for symbolic manipulation tasks. In McCarthy's seminal design, the interpreter's core functions and were defined using mutual recursion, enabling the computation of symbolic expressions through cyclic calls between evaluation and application steps. This approach facilitated 's role in research, where recursive structures modeled complex symbolic processes. Subsequently, , including mutual forms, became a key feature in the report published in 1960, influencing compiler design and procedural programming paradigms. The specification formalized recursive procedures, and early implementations often relied on mutually recursive subroutines to handle nested calls efficiently. In computing practice, mutual recursion is ubiquitous in , which form the front-end of many compilers. These parsers are constructed from a set of mutually recursive procedures, each corresponding to a non-terminal in the , allowing top-down of input tokens. For instance, the GNU Compiler Collection () employs a handwritten for and C++, switched from Bison-generated code in the early 2000s to improve error reporting and maintainability through mutual recursion among parsing functions. This pattern extends to other compiler front-ends, where mutual recursion naturally mirrors the grammar's recursive structure without requiring complex state management. Contemporary applications leverage mutual recursion in functional programming languages like and , particularly for traversing mutually recursive data types such as abstract syntax trees. In , recursion schemes like catamorphisms can be extended to handle mutual recursion, enabling composable traversals over structures like expression trees where nodes reference each other cyclically. Similarly, in , mutual recursion supports elegant implementations of tree traversals in interpreters and compilers. In game development, mutual recursion models finite state machines for behaviors, where state-handling functions call each other to transition based on events, as seen in functional implementations of non-player character logic. Despite its utility, mutual recursion poses challenges in imperative languages, primarily due to the risk of from deep call chains. In languages like or , each recursive call consumes stack space, and mutual recursion can exacerbate this by creating longer paths without tail-call optimization support, leading to runtime errors in non-trivial cases. This issue has prompted developers to limit its use in resource-constrained environments. Over time, particularly from the onward, programming practices in performance-critical domains shifted toward iterative constructs to mitigate recursion's overhead. Early studies on transforming to , including mutual cases, gained prominence as limitations highlighted usage inefficiencies, influencing optimizations in compilers and codebases favoring loops for . This evolution persists in modern imperative code, where mutual recursion is reserved for conceptual clarity in non-hot paths, while dominates for efficiency.

Use in Mathematics and Logic

Mutual recursion serves a foundational role in logic for defining inductive predicates, particularly through the framework of primitive recursive functions introduced by Kurt Gödel in 1931. Gödel employed these functions to arithmetize syntax in formal systems, enabling the encoding of provability and truth predicates via inductive definitions. The class of primitive recursive functions is closed under simultaneous recursion, allowing the definition of multiple interdependent functions, as formalized by Wilhelm Ackermann in 1928 and Rózsa Péter in 1934. This approach allows for the construction of complex logical structures while maintaining totality. In , mutual recursion facilitates the solution of functional equations involving interdependent relations, such as those arising in combinatorial . For instance, restricted set functions, which count partitions of a set under constraints like part size or pattern avoidance, are often defined via finitely many mutual recurrence relations over the integers. These relations capture the generating mechanisms for sequences like the number of partitions into distinct parts or those satisfying mutual difference conditions, providing closed-form insights into asymptotic growth and structural properties. Within proof theory, μ-recursive functions augment primitive recursion with a minimization operator to handle partiality. Developed in the 1930s by Gödel, Church, and Kleene, this class encompasses all partial recursive functions and demonstrates Turing completeness. The equivalence to Turing machines underscores the expressive power in formalizing computability. A key limitation of mutual recursion emerges in untyped , formalized by in 1936, where it can induce non-termination. Fixed-point combinators, essential for encoding recursive and mutually recursive definitions, permit terms like the self-applicating Ω that diverge into infinite β-reduction sequences without normalization, complicating proof of and necessitating restrictions in typed variants to guarantee termination.

Techniques for Handling Mutual Recursion

Conversion to Direct Recursion

One common technique for converting mutual recursion into direct recursion involves introducing a wrapper function that dispatches control flow based on an additional input parameter representing the current state or function variant. This approach encodes the mutual dependencies within a single recursive function, eliminating the need for cross-calls between multiple functions. Consider the classic example of mutual recursion used in programming implementations to check the parity of a n, where two functions even and odd call each other:
function even(n):
    if n == 0:
        return true
    else:
        return odd(n - 1)

function odd(n):
    if n == 0:
        return false
    else:
        return even(n - 1)
To transform this into direct recursion, introduce a is_even (or an enum for more functions) to track the expected state. The step-by-step is as follows:
  1. Define a single function parity(n, is_even) that takes the original input n and the state parameter is_even (true for even check, false for ).
  2. In the base case, return the value of is_even if n = 0.
  3. For the recursive case, flip the state parameter (negate is_even) and recurse on n - 1.
The resulting is:
[function](/page/Function) parity(n, is_even):
    if n == 0:
        return is_even
    else:
        return parity(n - 1, not is_even)
To check if n is even, invoke parity(n, true); for , parity(n, false). This preserves the original semantics, as the state parameter simulates the switch between the two original s. For a general applicable to mutual recursion involving k , encode the state using a , enum, or to represent which 's logic is active. The transformation proceeds by:
  1. Identifying the mutually recursive and their .
  2. Merging them into one f(args, state), where state is an enum or indexing the original (e.g., 0 for first, 1 for second).
  3. Replacing each mutual call with a recursive call to f with the updated arguments and the target state's .
  4. Ensuring base cases are handled uniformly based on the state.
Pseudocode for a two-function case f and g might look like:
enum [State](/page/State) { F, G }

function unified(args, [state](/page/State)):
    if base_case(args, state):
        return base_value(args, state)
    else:
        [match](/page/Match) state:
            case F:
                // Logic for f, including recursive call to g as unified(new_args, G)
            case G:
                // Logic for g, including recursive call to f as unified(new_args, F)
This method simulates mutual calls through state transitions within the single function. For more than two functions, extend the enum accordingly, though duplication may occur in the branches. The primary advantages include reducing the number of functions from multiple to one, which simplifies the call graph and can facilitate further optimizations like tail-call elimination in supportive environments. However, it increases code complexity by requiring explicit and may introduce minor overhead from parameter passing. Semantics are preserved provided base cases and state transitions accurately reflect the original mutual dependencies.

Language Support and Optimizations

Programming languages provide varying levels of built-in support for mutual recursion to facilitate its implementation without manual transformations. In and C++, forward declarations are essential for mutual recursion, as they allow a function to another before its complete definition, resolving compilation dependencies in header files or within the same translation unit. In functional languages like , mutual recursion is natively supported through grouped bindings in let or where expressions, enabling multiple s to recursively reference each other within the same scope via dependency analysis. Compilers and interpreters often optimize mutual recursion to improve efficiency and prevent resource exhaustion. Tail-call optimization (TCO) is a key technique, particularly for mutual recursion where the recursive call is the final operation in each function. In , the R5RS standard mandates proper recursion, ensuring implementations support an unbounded number of active calls without additional space, which applies to mutual cases when calls occur in positions. To mitigate overflows in languages lacking TCO, heap-based allocation strategies like can simulate calls by storing continuations on the rather than the call , allowing deep mutual recursion without fixed limits. At runtime, mutual recursion introduces considerations for concurrency and . In multithreaded environments, mutual recursion over shared data structures demands primitives, such as mutexes, to maintain and avoid race conditions during interleaved executions. In garbage-collected languages, recursive stack frames remain ineligible for collection until the recursion unwinds, exacerbating risks in deep mutual calls even as heap objects may be reclaimed. Certain language features can impose limitations on mutual recursion. Java's checked exceptions, for instance, require each mutually recursive method to declare all potential checked exceptions thrown by its counterparts, resulting in cluttered method signatures and increased boilerplate. Development tools aid in managing mutual recursion by detecting potential issues early. Integrated development environments like employ static analysis inspections to identify infinite recursion risks, including cycles in mutual recursive calls, by examining graphs and warning developers of non-terminating patterns.

References

  1. [1]
    Mutual recursion - Stony Brook Computer Science
    Mutual Recursion. Sometimes the most convenient way of defining (two or more different) functions is in mutual dependence of each other. Consider two ...Missing: science | Show results with:science
  2. [2]
    Reading 14: Recursion - MIT
    Mutual Recursion. Sometimes multiple helper methods cooperate in a recursive implementation. If method A calls method B, which then calls method A again, then A ...
  3. [3]
    (PDF) A gentle introduction to mutual recursion - ResearchGate
    Aug 7, 2025 · In comparison with direct recursion, mutual recursion is considered to be more complex. Consequently, it is generally addressed superficially in ...Missing: scholarly | Show results with:scholarly
  4. [4]
    Termination of Nested and Mutually Recursive Algorithms
    This paper deals with automated termination analysis for functional programs. Previously developed methods for automated termination proofs of functional ...
  5. [5]
    A gentle introduction to mutual recursion - ACM Digital Library
    This paper provides several intuitive and attractive algorithms that rely on mutual recursion, and which have been designed to help strengthen students' ability ...
  6. [6]
    A note on “On the conversion of indirect to direct recursion”
    It was claimed that for any call graph, there is a mutual-recursion elimination sequence if and only if no strongly connected component contains two node- ...
  7. [7]
    CMSC 202 Lecture Notes: Recursion - UMBC
    The following pair of functions is indirectly recursive. Since they call each other, they are also known as mutually recursive functions.
  8. [8]
    [PDF] Fast, accurate call graph profiling - Department of Computer Science
    strongly-connected component of the call graph (which it calls a 'cycle' in the report), aggregating the time taken by the routines themselves and the time ...
  9. [9]
    None
    ### Definitions and Properties of Recursion Types
  10. [10]
    [PDF] How to Think Like a Computer Scientist: Learning with Python 3 ...
    Apr 17, 2020 · The engine that translates and runs Python is called the Python ... Mutual Recursion. In addition to a function calling just itself, it ...
  11. [11]
    [PDF] Top Down Parsing - UT Computer Science
    Given parsing table, it is easy to generate recursive-descent parser. Page 31 ... descent parser that consists of a set of mutually recursive procedures.
  12. [12]
    An Introduction to Scheme and its Implementation - Recursion in ...
    In Scheme, these two procedures will repeatedly call each other, without saving their state on the stack, producing an infinite mutual recursion. Will the stack ...<|control11|><|separator|>
  13. [13]
    Recursive Functions - Stanford Encyclopedia of Philosophy
    Apr 23, 2020 · Section 3 provides an overview of computability theory, inclusive of the so-called Recursion Theorem (Section 3.4)—a result which highlights the ...
  14. [14]
    [PDF] FIBONACCI NUMBERS AND MATHEMATICAL EXPLORATIONS
    Definition by recursion. 29. 1. BIG! BIG!! BIG!!! 30. 2. More problems using ... Even + even. = even, even + odd = odd, even × anything = even, odd × odd =.
  15. [15]
    [PDF] Mu-Recursive Functions
    The values of Ackermann's function exhibit a remarkable rate of growth. By fixing the first variable, Ackermann's function generates the one-variable functions.
  16. [16]
    [PDF] arXiv:2108.03574v1 [math.LO] 8 Aug 2021
    Aug 8, 2021 · I have made the second choice—that algorithms are directly expressed by systems of mutual recursive definitions—and I have developed and ...
  17. [17]
    [PDF] Sums of Products for Mutually Recursive Datatypes
    Sep 27, 2018 · The mutual recursion is central to some applica- tions such as generic diffing [15] of abstract syntax trees. The motivation of our work stems ...
  18. [18]
    [PDF] Structure and Interpretation of Computer Programs - MIT
    ... Structure and Interpretation of Computer Programs, second edition. Harold ... Recursion and Iteration . . . . . . . . . 41. 1.2.2. Tree Recursion ...
  19. [19]
    [PDF] Recursive Functions of Symbolic Expressions and Their ...
    We shall first define a class of symbolic expressions in terms of ordered pairs and lists. Then we shall define five elementary functions and predicates, and ...
  20. [20]
    Recursive functions of symbolic expressions and their computation ...
    Recursive functions of symbolic expressions and their computation by machine, Part I. Author: John McCarthy.
  21. [21]
    Recursion - FICO
    In Mosel, it is also possible to use cross-recursion, that is, subroutine A calls subroutine B which again calls A. The only pre-requisite is that any ...
  22. [22]
    Classical (co)recursion: Mechanics | Journal of Functional ...
    Apr 4, 2023 · These (co)recursion schemes are captured by (co)data types whose duality is made apparent by the language of the abstract machine. In particular ...2 Recursion On Natural... · 3 Recursion In An Abstract... · 4 Corecursion In An Abstract...
  23. [23]
    SUBVERSIVE-RECURSIONS.html -- ACL2 Version 2.9
    That is, the constrained functions of an encapsulate should not be reachable in the dependency graph ... mutual recursion) as late as Version 2.3. We now ...
  24. [24]
    Mutual Recursion — Agda 2.9.0 documentation
    Mutual recursive functions can be written by placing the type signatures of all mutually recursive function before their definitions. The span of the mutual ...Missing: programming | Show results with:programming
  25. [25]
    Recursive Functions: The rec Keyword - F# - Microsoft Learn
    Oct 24, 2023 · Sometimes functions are mutually recursive, meaning that calls form a circle, where one function calls another which in turn calls the first, ...
  26. [26]
    [PDF] Lecture 3: Mutual Recursion & Tail Recursion
    Jan 28, 2025 · Mutually recursive types are separated by the word “and”. Notice that there is no “;;” before the “and” and there is no second “type” ...Missing: indirect | Show results with:indirect
  27. [27]
    Types of Recursions - GeeksforGeeks
    Jul 12, 2025 · The first one is called direct recursion and another one is called indirect recursion. Thus, the two types of recursion are:
  28. [28]
    [PDF] A Variadic Extension of Curry's Fixed-Point Combinator
    Fixed-point combinators are used in the λ-calculus to solve fixed-point equations. Given a term M, we are looking for a term x (in fact, the “smallest” such x ...
  29. [29]
    None
    Nothing is retrieved...<|separator|>
  30. [30]
    [PDF] On the Origin of Recursive Procedures
    Dec 11, 2014 · All in all, the existence of mutual recursion does not seem to be a totally convincing reason to consider that. Naur and Dijkstra are both wrong ...
  31. [31]
    Recursive descent parser - Wikipedia
    In computer science, a recursive descent parser is a kind of top-down parser built from a set of mutually recursive procedures (or a non-recursive equivalent)Example parser · C implementation · Examples
  32. [32]
    Recursive descent, LL and predictive parsers - Eli Bendersky's website
    Sep 26, 2008 · A recursive descent parser is a top-down parser built from a set of mutually-recursive procedures (or a non-recursive equivalent) where each ...
  33. [33]
    Mutually recursive traversals - Oleg Grenrus
    Aug 3, 2020 · If you have two mutually recursive types, then there are two mutually recursive traversals. They look like monomorphic Bitraversable .
  34. [34]
    Are there any examples of mutual recursion? - Stack Overflow
    Apr 27, 2010 · A recursive descent parser based on the grammar below will naturally contain mutual recursion: expression-terms-term-factor-primary-expression .recursive descent parser and functional programming - Stack Overflowparsing - How to write a parser for a mutually recursive ADT without ...More results from stackoverflow.com
  35. [35]
    What methods are there to avoid a stack overflow in a recursive ...
    Apr 11, 2013 · Another approach is to include a recursion counter. This is more for detecting infinite loops caused by situations beyond one's control (and poor coding).Missing: mutual stacks
  36. [36]
    From recursion to iteration - ACM Digital Library
    Transforming recursion into iteration eliminates the use of stack frames during program execution. It has been studied extensively.Missing: evolution shift
  37. [37]
    [PDF] From recursion to iteration: what are the optimizations?
    Abstract. Transforming recursion into iteration eliminates the use of stack frames during program ex- ecution. It has been studied extensively.
  38. [38]
    [PDF] MC-Finiteness of Restricted Set Partition Functions
    It is based on the existence of finitely many mutual polynomial recurrence relations over Z that are used to define the integer sequence. In a separate paper, ...
  39. [39]
    [PDF] Generating Mutually Recursive Definitions
    converted to the ordinary recursive function by adding an extra argument: the index of a particular recursive clause in the group1: type evod = Even | Odd.Missing: parameter | Show results with:parameter
  40. [40]
    On the conversion of indirect to direct recursion - ACM Digital Library
    Procedure inlining can be used to convert mutual recursion to direct recursion. This allows use of optimization techniques that are most easily applied to ...
  41. [41]
    2.7 — Forward declarations and definitions - Learn C++
    Jun 2, 2007 · A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier.
  42. [42]
    The Haskell 98 Report: Declarations
    ### Summary of Mutual Recursion in Haskell from https://www.haskell.org/onlinereport/decls.html
  43. [43]
    Proper tail recursion - Revised(5) Scheme - People | MIT CSAIL
    A Scheme implementation is properly tail-recursive if it supports an unbounded number of active tail calls. A call is active if the called procedure may still ...
  44. [44]
    What Is Thread-Safety and How to Achieve It? | Baeldung
    Jun 11, 2024 · This programming methodology is known as “thread-safety.” In this tutorial, we'll look at different approaches to achieve it.3. Immutable Implementations · 4. Thread-Local Fields · 11. Reentrant LocksMissing: recursion | Show results with:recursion
  45. [45]
    Garbage Collection in Java with Recursive Function - Stack Overflow
    Jan 5, 2015 · I know that objects become unreachable and marked for garbage collection in every iteration of a regular loop. What about recursive calls?Does java recursion algorithms consume more heap causing ...Do recursive sequences leak memory? - Stack OverflowMore results from stackoverflow.comMissing: mutual | Show results with:mutual
  46. [46]
    Java Checked vs Unchecked Exceptions - GeeksforGeeks
    Oct 2, 2025 · Checked exceptions represent invalid conditions in areas outside the immediate control of the program like memory, network, file system, etc.
  47. [47]
    Infinite recursion | Inspectopedia Documentation - JetBrains
    Sep 18, 2025 · Path to the inspection settings via IntelliJ Platform IDE Settings dialog, when you need to adjust inspection settings directly from your IDE.