A real world case of recursion done right in PHP
Nick Cosentino @DevLeaderCa posted this message about recursion on X, ex Twitter, in October 2025, which received over 460 replies. // Detect dark theme var iframe = document.getElementById('tweet-1984123215170421060-448'); if (document.body.className.includes('dark-theme')) { iframe.sr

Nick Cosentino @DevLeaderCa posted this message about recursion on X, ex Twitter, in October 2025, which received over 460 replies. // Detect dark theme var iframe = document.getElementById('tweet-1984123215170421060-448'); if (document.body.className.includes('dark-theme')) { iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1984123215170421060&theme=dark" } I quote an excerpt: I've found that converting over to an iterative loop based approach is almost always more readable and easier to debug. He explains that in over 20 years of programming, he has never used recursion, thus questioning its usefulness. In this article, I show a real case where I used recursion, and where I think that it is much simpler than its iterative counterpart. But before going any further, let see what makes a recursive algorithm powerful. To understand the value of recursion, let's look at the implementations with and without recursion of an algorithm very often used to illustrate it: the Fibonacci sequence. Here's the recursive algorithm. if n = 0 or n = 1 then fib(n) = 1 else fib(n) = fib(n β 1) + fib(n β 2) endif And here's the iterative one. if n = 0 or n = 1 then fib(n) = 1 else a = 1 b = 1 for i in 2 .. n do c = a + b a = b b = c endfor fib(n) = c endif This simple example demonstrates the advantages of recursion: no loops and no intermediate variables. This also gives us an indication of when recursion is advantageous, namely when the function can be defined with a simple expression depending on itself. This might not be the case for example when the data being processed is a graph instead of a tree. The library we'll be talking about is the PHP UI Builder. It builds application UIs using components, as defined by CSS frameworks. It provides a common API which defines the components, and from which specialized libraries can generate HTML code for a given CSS framework, like Bootstrap, Bulma or Tailwind CSS. With its hierarchical component structure, a UI is particularly well-suited to a recursive algorithm. A component has properties, but can also contain components that themselves have some properties and can contain other components, and so on. When building a UI from data, the result can sometimes vary depending on their values. Some components will only be created under certain conditions, others are multiplied according to the entries in a list or loop, and others may be an aggregate of different components. To represent these cases, our library introduces the concept of virtual components. These are components that take a set of data as input and produce as output a set of zero or more components, which may or may not be virtual. There are 4 of them: When: takes a condition as input and generates a component if it is met. Each: takes an array of data as input and generates a component for each element. Pick: takes a list of conditions as input and generates a different component depending on the first one that is true. List: aggregates any set of components into one. A UI will ultimately consist of a tree structure of components, each of which can be virtual or real. A real component can have several children, each of which can be virtual or real, and a virtual component generates a list of components, each of which can be virtual or real. Here's an example of a function using the UI library. /** * @param array $collations * * @return string */ public function addDbForm(array $collations): string { return $this->ui->build( $this->ui->form( $this->ui->row( $this->ui->col( $this->ui->label($this->ui->text('Name')) ->setFor('name') )->unit(1, 4), $this->ui->col( $this->ui->input() ->setType('text') ->setName('name') )->unit(1, 2) ), $this->ui->when(count($collations) === 0, fn() => $this->ui->input() ->setType('hidden') ->setName('collation') ->setValue('')), $this->ui->when(count($collations) > 0, fn() => $this->ui->row( $this->ui->col( $this->ui->label($this->ui->text('Collation')) ->setFor('collation') )->unit(1, 4), $this->ui->col( $this->ui->select( $this->ui->option('(collation)') ->setValue('') ->selected(true), $this->ui->each($collations, fn($_collations, $group) => $this->ui->pick( $this->ui->when($group === '', fn() => $this->ui->each($_collations, fn($collation) => $this->ui->option($collation) ) ), $this->ui->when(true, fn() => $this->ui->optgroup( $this->ui->each($_collations, fn($collation) => $this->ui->option($collation) ) )->setLabel($group) ) ) ) )->setName('collation') )->width(6) ) ) ) ); } To generate a UI from a component tree, we will use the following algorithm: function build(c) children = [] expand(c, children) c.elements = [] for child in children if child is a component then build(child) append child.elements to c.elements else append child to c.elements endif endfor endfunction function expand(c, children) if c is virtual then for child in c.children expand(child, children) endfor else append c to children endif endfunction What we have here is actually a combination of two recursive functions. The expand() function returns the list of real components generated by a virtual component. It will therefore iterate recursively over all its children as long as virtual components are present. The build() function, which is the entry point for the process, first calls the expand() function. Its list of children then consists only of real components, on which it executes recursively. The final result is in the Scope class. In their PHP implementation, the recursive expand() function is 15 lines of code long, and the build() function is 40. Two extremely simple functions, which form the basis that allows the implementation in a single library of both the templating functionalities of libraries such as Twig or Blade, and the HTML code generation of libraries such as Spatie's HTML Builder or Symfony's Forms component (the rendering part). The UI library is used to build the Jaxon DbAdmin UI, demonstrating that it allows the construction of complex UIs, calling classes and their methods instead of writing HTML templates. Nick Cosentino's message rightly points out two drawbacks of recursion, which we will briefly discuss here. First, it's absolutely true that recursion is difficult to debug, particularly because mentally unraveling the instructions executed by a recursive algorithm is very complex. However, at the same time, the simplicity of recursive algorithms leaves little chance for a bug to occur. Therefore, before choosing recursion, it's important to ensure that the algorithm being implemented can be expressed very simply in a recursive manner. This is indeed the case for the Fibonacci sequence and our library. Implementing a recursive algorithm can consume a significant amount of memory, depending on the level of nesting of the calls. Moreover, PHP imposes a limit on the number of nested calls within a recursive function, and the consequence of an overflow will be to fail a single call, not to crash the entire server. To answer Nick Cosentino's initial question, of course it is possible to create all sorts of complex software without using recursion. However, this doesn't mean it can always be replaced by an iterative version, but rather that cases where one can fully leverage all its advantages are not very common.
Key Takeaways
- β’Nick Cosentino @DevLeaderCa posted this message about recursion on X, ex Twitter, in October 2025, which received over 460 replies. // Detect dark theme var iframe = document.getElementById('tweet-1984123215170421060-448'); if (document.body.className.includes('dark-theme')) { iframe.sr
- β’This story was reported by Dev.to, covering developments in the dev space.
- β’AI advancements continue to reshape industries β read the full article on Dev.to for complete coverage.
π Continue reading the full article:
Read Full Article on Dev.to βShare this article



