My thoughts exactly, if you want to stay in this breakable loop formula, then this is what you’re looking for, assuming this is local.
I guess you could try using Heartbeat
or Stepped
or RenderStepped
.
Actually, for a better alternative of most cases. You should utilize signals that indicate something has changed. Once that property changes, fire a function from that point.
If they have the run service functions, then shouldn’t while loops be deprecated by now? If they provide a use that run service doesn’t have then this issue still needs to be addressed. @wastemanty23 @RepValor
I think you can break a runservice loop by using :Disconnect()
I’ll edit this post with an example if I can come up with one.
Provided that while
can still work in cases that other functionalities don’t, it’s a fundamental method. You can combine RunService
replacing wait()
and the while
loop that checks for a condition, not breaking it, which can for instance create a timer.
Once the condition is not matching, it will cease.
Additionally, wait()
is already basic for a new developer. We can’t just dive into the advanced for them, yet. It’s because of backwards compatibility.
I know this can be done, but if while loops have some use, using hacky ways to use it is bad practice to developers who use it.
Never thought of using RunService functions inside a while loop. I am still confused on why while loops are not deprecated because the best way to use it is through runservice functions which is the same as just connecting a runservice event.
While loops are not inherently designed for infinite loops.
I agree that it doesn’t seem like you would have much use for them over for loops, however there are times and places where while loops are very great.
Imagine you need to loop an uncertain number of times, all you know is the condition in which you need to stop looping, well bam that’s what a while loop is for.
While loops are not deprecated because they’re a fundamental basic of all programming. They are a requirement in a turing complete language, and they’re really handy.
You could use a delay function and count the times it runs. Then after a certain amount of times it runs, it is disconnected which has the same functionality as while loops. Your points does clear up the fog on why while loops are in lua, but while loop functionalities can be created with using other methods with better performance and less memory leaks.
There are so many reasons why this is wrong, but I’ll just simply state my biggest complaint.
What if you need the loop to be synchronous?
Oh well then you can just implement some checks in the RunService
loop.
Alright, let’s see what that looks like:
local MyNumCounter
local MyNumInitiated = false
local MyNum = math.floor(math.random(1, 10))
MyNumCounter = game:GetService("RunService").Stepped:Connect(function()
if not MyNumInitiated then return end
MyNum -= 1
if MyNum <= 0 then MyNumCounter:Disconnect() end
end)
MyNumInitiated = true
repeat wait() until MyNum <= 0
print("Loop done!")
Amazing, now let’s see what that looks like with a while loop…
local MyNum = math.floor(math.random(1, 10))
while MyNum > 0 do
MyNum -= 1
end
print("Loop Done!")
Do you see yet what I’m saying?
I do understand your points (and they are really good) but you would have to add a yield which would require an alternative to wait for the most efficient results.
wait()
is inconsitent in nature, it waits a minimum of 29ms.
RunService (and all events technically) have a :Wait
function, where the code will yield until the event is signalled, this can still get delayed just like wait(), however its not as likely, in fact it nearly never happens since ScriptSignal:Wait() is put in the primary queue, while wait() is put in the secondary queue
while true do
local delta = RunService.Heartbeat:Wait()
print("hello world")
end
No, see while loops are most efficient when there is no delay. You don’t need a yield unless the loop is infinite, or very long within reason.
While loops are meant to run at thread speed to perform a task an uncertain number of times instantly.
That is the same as connecting a heartbeat event though.
:Wait
doesn’t create a RBXScriptConnection which means you dont need to do any cleanup if you were to break the loop.
That would still require a yield though and could be bypassed by using wait(0). I know it the loop time isn’t long but it still can cause a script timeout.
I meant if I were to replace the :Wait with :Connect(function() that it would act the same as the while loop with RunService.Heartbeat:Wait()
This is getting a little far from the original question, but I think you really really need to hear this.
You can not simulate a while loop using a RunService
loop efficiently. Not all loops require a yield.
Specifically, while loops shouldn’t have yields, it’s bad practice to make an infinite while loop, or to even yield it unless you’re looping an absurdly large amount of times.
The purpose of a while loop is not to be a scheduled loop in a proper interval, it is meant to be an instantaneous code executor. You can not run code instantaneously in an interval loop.
Really I’m not certain what it is about this you don’t get, you’re wondering why while loops aren’t deprecated? Alright then similarly why aren’t for loops deprecated, or if statements, or variable creation?
You don’t deprecate a fundamental basic of programming, these are literally requirements in the turing test.
I do agree with you now but in the API, it states it can be used for infinite loops:
The
while
—do
loop can also be used for infinite game loops by using simplytrue
as the condition.
Always include a delay such as
wait()
inside an infinite loop, as omitting it can freeze the game.
It even has the bad practice.
I don’t want to stray to far from this question but I feel as though this is needed for a good grip on while loops.