I’ve been wondering about this. When is it actually necessary to execute immediately, that isn’t covered by just calling the function directly?
Consider this example:
CallA()
coroutine.wrap(function()
print("foo")
wait(1)
print("bar")
end)()
CallB()
This can be rewritten to remove the coroutine entirely:
CallA()
print("foo")
delay(1, function()
print("bar")
end)
CallB()
How about this more complex example:
CallA()
coroutine.wrap(function()
for i = 1, 10 do
print("foo", i)
wait(1)
print("bar", i)
end
end)()
CallB()
This one is interesting, because it contains behavior that I would consider undesirable. That is, the first “foo” action executes before the caller, while every subsequent “foo” and “bar” action executes after. Surely it would make more sense for these actions to be grouped together in relation to the caller.
This can be done by either calling/inlining the function directly, causing the caller to depend on the actions, or using spawn
, in which case the caller does not depend on the actions. By avoiding coroutines, the order of execution becomes more clear.
-- Everything occurs before CallB().
CallA()
(function()
for i = 1, 10 do
print("foo", i)
wait(1)
print("bar", i)
end
end)()
CallB()
-- Everything occurs after CallB().
CallA()
spawn(function()
for i = 1, 10 do
print("foo", i)
wait(1)
print("bar", i)
end
end)
CallB()
Signals also have this coroutine-like behavior. It makes me wonder how many bugs are caused by things being unintentionally executed out of order.