Does infinite recursive function calling is bad?

Hi guys. Today I have tried to do function which will update smth forewer in set interval. And I have found nothing better than recursion. But does it has any drawbacks like memory leak, cuz this recursion won’t end at all.

Example of such recursion:

function recursion()
    --do smth
    task.wait(5)
    recursion()
end
recursion()

Totally fine to use. It will use the same memory address.

Not really. It would just be the same as creating a while loop.

It will consume more memory than a traditional while loop and will eventually stack overflow as well. For something that does not need recursion, don’t use it.

2 Likes

Incorrect. First part is “technically speaking”, but it uses a single memory address in this case and wont consume any more memory than a traditional while loop. The second part will not stack overflow with a delay.

2 Likes

Where are you getting this information?

The language will have to store the function call order in a stack every time you call a function. This requires memory. It’s the sole reason debug.traceback() works.

For the case of recursion:

It does not matter if there’s a delay or no delay. There is a limit and using a yield will only delay such error.

2 Likes

Hm, can coroutines help to avoid stack overflowing?

function recursion()
    -- do smth
    coroutine.wrap(function()
        task.wait(5)
        recursion()
    end)()
end

recursion()
1 Like

Oh that thread’s pretty interesting. Seems like it stack overflows just before being ran 20k times.

I decided to test this out myself and it actually gave the result:

2 Likes

A lot! I don’t think that with my 3-hour cooldown I’ll hit 20k recursive calls, but still - if there’s limit, then everything is stored somewhere.

2 Likes

It appears I was wrong and forgot about the stack limit (which is indeed 20k), but Luau can cache a function with closure caching, unless I’m interpreting this incorrectly and would love some insights to it: Performance - Luau

…when multiple executions of the same function expression are guaranteed to result in the function object that is semantically identical, the compiler may cache the closure and always return the same object

If you print the memory address of the function (in this case, the recursive function), it will always return the same memory address.

Edit: To test this, I ran this piece of code to see if I would get any major spikes in memory:

task.wait(1)

local i: number = 0

while i < 1000 do
	task.wait()
	i += 1
	print("while loop")
end

task.wait(1)

i = 0

local function recur(): ()
	task.wait()
	i += 1
	print("recur")
	
	if i == 1000 then
		return
	end
	
	recur()
end

recur()

About halfway through this graph ran the recursive function. It resulted in virtually no changes in memory.