Recursive Programming: Example and Disadvantages

Video thumbnail

I want to talk a little about a topic I find very interesting: recursion, or recursive programming. In short, you may not be familiar with it, as it's a topic I don't really see mentioned much these days. It's something I brought up from university, and since then, in all the courses and books I've read, I've never really seen it mentioned again.

That's why I thought it would be interesting to bring it up here, as it can be very useful in certain situations. If you're already familiar with it, you'll know it has its advantages and disadvantages, but as they say, you have to know how to implement it well. So I want to show you a practical example of how I'm using it.

The Case Study: HTML to Native Widgets

As I mentioned before, I created a small implementation based on an HTML file. Everything you see is a plain HTML page, with its images, divs, lists (ul, ol), paragraphs, etc. The interesting thing I wanted to do was translate that HTML (which was originally in a web viewer) into native widgets. This, of course, brings many advantages, although I won't go into that in depth now.

The important thing here is that recursion helped me a lot. You'll understand why.

The Problem with Nested Divs

I have a function called htmlToWidget, which is responsible for processing the HTML document. Basically, once I get the document, I start iterating through it and checking what type of node it is: if it's an H1, an H2, a p, an img, a ul, etc., and based on that, I generate the corresponding widget.

Everything works fine... until the divs appear.

The problem is that a div can contain more HTML elements inside. And if we do it the traditional way, only the direct children are searched. But many of those elements can be more deeply nested. For example, in structures like this:

<div>
 <div>
   <section>
     <p>Texto</p>
   </section>
 </div>
</div>

If we only iterate through the direct children, we'll lose much of the content, as it's not accessible at the first level of iteration.

Recursive Solution

When I encounter a div or section, I call a function called share, which, in turn, calls processHTML, which is recursive. That is, if I encounter a div, I pass its children to that function, and so on.

switch (element.localName) {
      case 'h1':
      case 'h2':
      case 'h3':
      case 'h4':
      case 'h5':
      case 'h6':
        Text(...)
        break;
      case 'ul':
      case 'ol':
        Text(...)
        break;
      case 'p':
        Text(...)
        break;
      case 'img':
        return [processImage(element)];
      case 'div':
      case 'section':
        // buscamos contenido interno
        return _searchContent(element, context);

    }
    


  List<Widget> _searchContent(html_dom.Element element, BuildContext context) {
    // Función auxiliar para buscar contenido dentro de un section

    if (element.children.isEmpty) return [];

    List<Widget> ws = [];
    element.children.forEach((e) {
      _processHTML(e, context).forEach((w) {
        ws.add(w);
      });
    });

    return ws;
  }


The function will process the first div, then the child, then the h2, then the p, and so on until it reaches the content I want to display in the widget.

This is where recursion shines. If I didn't use it, I'd have to create multiple nested forEach statements or copy and paste logic into different blocks. It would be a hassle to manage each level of nesting manually.

Disadvantages of Recursion

Before finishing, I want to briefly discuss its disadvantages, because it must be used with caution:

  1. Higher memory consumption: because each recursive call remains on the stack.
  2. Stack overflow: If not properly controlled, it can generate errors.
  3. Difficult to debug: Tracing calls can be more complex than with traditional loops.
  4. Lower efficiency: It can be less performant than a plain forEach statement.

That's why I understand why it's been a somewhat abandoned concept. But, as I show you here, there are cases where it is the right tool.

I agree to receive announcements of interest about this Blog.

Recursion is wonderful, I'll show you an example of the implementation of html to widgets.

- Andrés Cruz

En español