Is it possible to never return a function?

Because coroutine.wrap() returns a function that resumes the coroutine each time it is called. And I think that just complicates things when you want to cancel the thread? coroutine.create() returns you the thread and you can cancel it whenever you want, so I think that’s more convenient.

Right. Thanks a ton for your extended assistance helping me clean this up. I appreciate your time :slightly_smiling_face:

1 Like

You are welcome, but I still wouldn’t recommend this, this feels overengineered.

I’d recommend just doing this because it’s the simplest and most efficient.

Haha, 23 replies later, I would say so too.

I will probably stick with the traditional method since writing coroutine.create and coroutine.resume every time is arguably even more verbose. This was more of an exercise than anything. I do think it would make sense for languages to offer the option to never return a function though.

I am sure that’s a thing already, you don’t have to include return at the end of your function in lua, it could just be:

local function func()
 -- some code
end

return just means when the function finishes, return me some values. What you want to do can be done by 1 if statement, that’s as good as it gets. It’s not verbos when that’s the “only” way it can be done.

Yup, that returns void (I think it appears as nil in Roblox). By not returning I mean what this whole thing was about (cancelling the function/not continuing).

The whole coroutine thing is more verbose than just using an if statement which is what makes it overengineered.

The only reason we are able to do this in lua is because it’s “multi-threaded”, other languages don’t even have the option to cancel the function like you want, so a simple if statement is the most grounded and basic way to do it.

You’ll get used to your code having a lot of if return end because of this, so don’t worry about that :smile:

Yeah, it’s good to know it can be done, albeit in a roundabout way lol. It would just be nice if it were a native feature because there are benefits to it.

That’s what I’ve been doing this whole time. Code redundancy makes me frustrated!

1 Like

coroutine.wrap() “works without a coroutine” because you are in a coroutine, no matter what you think or do.
A coroutine is created for you to run your scripts and your events. It’s nothing special whatsoever, it’s just how Lua works.
The beauty of it is that you don’t need to think or know about it most of the time.

You do not need to coroutine.create or coroutine.wrap for it to work.
However, you may need it to limit its effects if you’re putting this code in a function.

Good one, I couldn’t find any sign of it from the docs from two searches, though.
You should do

task.cancel(coroutine.running())

to terminate the current thread (instead of just abandoning it).
I don’t actually know whether task.cancel can actually do that.

As for the memory leaks:

Garbage collection occurs as normal and there should be no memory leak. I should’ve googled this earlier.

The saga never dies!

Interestingg, that makes a lot more sense now.

Yep, Roblox dev docs is missing a few things. There’s also a relatively new coroutine method that hasn’t been documented.

If I don’t have to use coroutine.create then it might be worth using this method after all. Thanks for the follow up!

Breaking will stop the while loop, and by extension the script, and I’m not sure where you’re getting the notion they are expensive.

While loops are not inherently expensive but would be if applied to this case.

I believe there is a misunderstanding. The message you initially replied to was simply demonstrating how the if value then ... end check becomes repetitive when the function is used several times. Each of those blocks would be in a separate section. You may have been under the impression that it was sequential which is why I think you suggested a loop.

The problem with that is that I won’t be able to cancel the thread from another thread, so if I want to do that I do task.cancel(targetThread)

task.cancel takes the thread and just kills it, so everything related to that thread gets gc’ed, but since you mentioned that stackoverflow link where yielded threads do get gc’ed, i wouldn’t even worry about canceling my thread, i’ll just coroutine.yield() and let the gc handle it for me. Thanks for showing me that, I’ve been looking for that answer for a while now here.

Oh also, coroutine and thread is synonymous in lua, so i don’t really get what you mean by this.

1 Like