🎓 A1Learner
🔍
0 of 49 lessons completed

Lua Nested Coroutine Yields

A nested coroutine yield is a yield called from a function that a coroutine called. The yield still reaches the resumer, even though the yielding code sits several calls deep.

A yield inside a helper reaches the resumer

The coroutine calls a helper, and the helper yields. The resume still returns the yielded value.

local function helper()
  coroutine.yield("from helper")
  print("helper done")
end
local co = coroutine.create(function()
  helper()
end)
local ok, value = coroutine.resume(co)
print(value)
coroutine.resume(co)

Yields cross two levels of calls

The outer function calls the middle one, which calls the inner one, and the inner one yields. The value still arrives at the resumer.

local function inner()
  coroutine.yield("deep")
end
local function middle()
  inner()
end
local function outer()
  middle()
  print("outer done")
end
local co = coroutine.create(outer)
local ok, value = coroutine.resume(co)
print(value)
coroutine.resume(co)

Nested yields arrive in order

A helper yields three values in a loop. The main code resumes three times and prints each value as it arrives.

local function helper()
  for i = 1, 3 do
    coroutine.yield(i * 10)
  end
end
local co = coroutine.create(function()
  helper()
end)
for _ = 1, 3 do
  local ok, value = coroutine.resume(co)
  print(value)
end

Example

local function double(n)
  coroutine.yield(n * 2)
end
local function process(values)
  for _, v in ipairs(values) do
    double(v)
  end
end
local co = coroutine.create(function()
  process({1, 2, 3})
end)
while coroutine.status(co) ~= "dead" do
  local ok, value = coroutine.resume(co)
  if value ~= nil then
    print(value)
  end
end

Key points

  • Nested call: a function called by another function inside the same coroutine.
  • Yield crossing: a yield inside a nested function suspends the whole coroutine, not just that function.
  • Resumer: the code outside the coroutine that receives the yielded value on resume.
  • Return path: when the coroutine is resumed again, the nested function continues right after its yield.
  • Order: values yielded from nested calls arrive at the resumer in the order the yields run.

In this example, the coroutine calls process, which calls double for each input value. Each double call yields its doubled value across two call levels to the main loop, which prints 2, 4, then 6 in order.

Note

the call stack is kept while the coroutine is suspended, so locals in every level survive the yield.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A coroutine calls function A, A calls function B, and B yields "x". Who receives "x"?