Recursive functions

What happens when a function tries to run itself? Recursion!?

by VitalWinter

Author Avatar

What it recursion?

Recursion occures when a thing is defined in terms of itself..

This is how wiki defines it. But what does it mean in our context? A recursive process is a process that will re-apply itself within itself.

Recursive functions are common in computer science because they allow programmers to write efficient programs using a minimal amount of code. The downside is that they can cause infinite loops and other unexpected results when not written properly.

In this tutorial I'll show you how to make a recursive function, and what recursive processes can be useful for.

As we know, we can define a function with the following code:

function doStuff(parameter)
    --things happen here
end

and we can execute the function like this:

doStuff(parameter)

Any code that we put inside of the function will be executed when the function is executed.

So what happens if the code inside the function tries to call itself?

When you execute the function, it will trigger a chain reaction where the function will execute again, and then again, and again again againagainagain.. And good job. You've created a paradox and caused the universe to break. Just kidding. You've created a paradox and caused your code to break.

img|2005x425

With great power comes great responsibility. You'll want to make sure that your recursive processes will eventually stop calling themselves. To see what I mean, lets do an example.

Example: Recolor all parts in a model.. using a recusive process.

Lets start by making a function that would recolor a thing if it is a part.

function colorPart(child, color)
    if child:IsA('BasePart') then
        child.BrickColor = color
    end
end

Lets also get some code that would call this function on all of a model's children.

local targetModel = workspace:WaitForChild('RedCar')
local targetColor = BrickColor.new('Bright blue')
for _,child in pairs(model:GetChildren())
    colorPart(child, targetColor)
end

This code works great.. except.. only parts that are directly parented under the model will be recolored. We also want the code to color parts that could be children of children, or children of children of children, and so on.. Sounds like a job for RECUSION! Lets try combinding our existing code into a recursive function.

function recursiveColor(object, color)
    if object:IsA('BasePart') then
        object.BrickColor = color
    end
    if _,child in pairs(object:GetChildren()) do
        recursiveColor(child, color)
    end
end

targetModel = workspace:WaitForChild('RedCar')
targetColor = BrickColor.new('Bright blue')
recursiveColor(targetModel, targetColor)

We did it! This colored our red car blue! How did we avoid creating an infinite recusion? In this case, our recusive function will call itself, but only with the children of the object it was handed. Naturally, objects cannot be parented in a circle, so it didn't get caught in any loop.

That example is quite basic, and actually could have been written another way using :GetDescendants(). But lets not think about that.

Look at this awesome power we've just aquired! You will typically find good use in it when doing more complex programming tasks such as pathfinding algorithims or fractal generation.

Try it out yourself and add this tool to your toolbelt.

View in-game to comment, award, and more!