Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Can someone explain in simple words what recursion is?

Asked by
Cikeruw 14
2 years ago

Some help would be nice. All of the definitions I’m looking up are very complex

3 answers

Log in to vote
0
Answered by
Xapelize 2658 Moderation Voter Community Moderator
2 years ago
local function f() 
    f() -- this is a recursion 
end

because you are calling f() in the f function, so it runs function f again, repeat, repeat and repeat, this is a recursion

:GetFullName() function also uses recursion, heres an example

local function GetFullName(instance) 
    local FullName = instance.Name

    local function AddParentNameToFullName(instance)
        FullName = FullName .. "." .. instance.Parent.Name
        if instance.Parent.Parent ~= game then
            AddParentNameToFullName(instance.Parent)
        end
    end

    AddParentNameToFullName(instance) 

    return FullName
end

sorry 3 battery on my phone so cant tell more

Ad
Log in to vote
1
Answered by 2 years ago
Edited 2 years ago

"A function/method that calls itself in the same scope/environment"?

Log in to vote
1
Answered by
imKirda 4491 Moderation Voter Community Moderator
2 years ago

(I am Xapelize No. 2) Before understanding recursion, let's make you pro at functions, what really is a function...

Think of function as a group of some code stored somewhere in your computer. Your code runs line by line, say you have 10 lines, at first, line 1 will be executed, after that line 2, that's obvious, however, what if you wrote code that kills everyone on the server:

-- Think as if this was real code

get all players
get their humanoids
set their health to 0

It takes 3 lines, good enough, but what if you wanted to use this piece of code again somewhere, absolutely same code without any changes, you could duplicate it:

get all players
get their humanoids
set their health to 0

... some more random code

get all players
get their humanoids
set their health to 0

But that will make the code unnecessary complicated and longer than it should be. What instead you can do is take these 3 lines of code and put them into a group, or into a model, or into a folder, whatever you want to call it, it's usually (always) called function.

create function named kill-all-players
(
    get all players
    get their humanoids
    set their health to 0
)

Say this will create the function, it will have these 3 lines as it's content, called function body. I named the function kill-all-players so we can use it later (if we created more functions we must somehow identify them, right). Next time we want to kill every player, instead of writing these 3 lines again, tell Roblox that you already did that, you give Roblox name of function and Roblox will look for it, when it finds it, it will see that it has 3 lines and execute them:


kill-all-players ... some other code kill-all-players

Now the code is easier to understand. What happened is that code literally jumped to that function:

create function named kill-all-players
(
    get all players
    get their humanoids
    set their health to 0
    -- Jumps back to line 10
)

kill-all-players -- Jumps to line 3

In Roblox the code would actually look like this:

local function kill_all_players()
    -- get all players
    -- get their humanoids
    -- set their health to 0

    -- Jumps back to line 10
end

kill_all_players() -- Jumps to line 2

But since you can execute this kill_all_players function anywhere, what if you were to execute it in the function body itself, like this:

local function kill_all_players()

    kill_all_players() -- Jumps to line 2

end

kill_all_players() -- Jumps to line 2

Just this is already called recursion, function executed itself. What would happen is that first Roblox would create a function kill_all_players, then at line 7 it would jump at line 2 (start of kill_all_players's function body) and then proceed to line 3, then it would jump at line 2 again since that's how function execution works, then it would proceed to line 3 again, then at line 3 it would jump at line 2 again, then it would proceed to line 3 again, then again jump to line 2 and so on infinitely.

So far we created while true do loop, useless and will just break the code. But maybe you could create a counter variable to prevent infinite loop:

local counter = 0

local function kill_all_players()

    counter += 1

    print("I got called for the " .. counter .. " time!")

    if counter < 10 then
        kill_all_players() 
    end

end

kill_all_players()

What happens is that at line 15 the code jumps at line 4, proceeds to line 5 and increases counter (which is 0) by 1, then it prints something, after that it checks if the counter is lower than 10, indeed, 1 is lower than 10, so, it runs on line 10 which executes the same function, thus it goes to line 4 again and proceeds to line 5, increases counter by 1 again and prints it, now it's 2, but 2 is still lower than 10 so it repeats this. When counter hits number 10, then is no longer executed and thus the function hits line 12 at which it goes back to line 16.

Practical use case might be when you want to display table, say you have table like this:

local t = {
    a = {
        a = 1239812938,
        b = 234982394,
        c = 4593284923
    },
    b = 34892034234,
    c = 43294879238,
    d = {
        e = {
            34829047882347823,
            423974823742348,
        },
        23740237482374,
        4573284752839
    }
}

Such table has random numbers in it, but, it also has so called nested tables, these are another tables with numbers in it. If you would want to print it, you'd need to get all the numbers from this, using recursion the logic would be the following: 1) Loop through elements on first layer first, these are a, b, c and c, b and c are numbers, print them 2) a and d are tables, what we can do is execute the same function which will go to step 1) and Loop through elements on the layer a, there it will see elements a, b and c, these are no longer tables so we can print them! 3) Do same for every nested table in nested table in nested table maybe

Or in code:

local function print_table(super_table)

    for key, value in pairs(super_table) do
        -- Check every element in *super_table*

        if type(value) == "table" then
            -- Value is table, jump to line 2, but this *super_table* is
            -- replaced with *value* which in first case will be the *a* element
            -- then it will be the *d* element, then the *e* element
            print_table(value)
        else
            -- value is not table, print it like a pro
            print(value)
        end
    end
end

print_table(t)

1239812938 234982394 4593284923 34892034234 43294879238 34829047882347823 423974823742348 23740237482374 4573284752839

Answer this question