Use when lua coroutines for cooperative multitasking including coroutine creation, yielding and resuming, passing values, generators, iterators, asynchronous patterns, state machines, and producer-consumer implementations.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Use when lua coroutines for cooperative multitasking including coroutine creation, yielding and resuming, passing values, generators, iterators, asynchronous patterns, state machines, and producer-consumer implementations.
allowed-tools
[]
Lua Coroutines
Introduction
Coroutines in Lua provide cooperative multitasking, enabling functions to
suspend and resume execution. Unlike threads, coroutines don't run in parallel
but yield control explicitly, making them simpler to reason about while enabling
powerful asynchronous patterns without callback complexity.
Coroutines are first-class values in Lua, created from functions and managed
through the coroutine library. They maintain their own stack, local variables,
and instruction pointer, allowing suspension at any point and resumption later.
This enables elegant implementations of generators, iterators, and state machines.
This skill covers coroutine basics, yielding and resuming with values, generators
and iterators, producer-consumer patterns, asynchronous I/O simulation, state
machines, error handling, and practical coroutine patterns.
Coroutine Fundamentals
Coroutines enable functions to pause and resume execution, providing cooperative
multitasking without thread complexity.
Coroutines enable cooperative multitasking where functions explicitly yield
control rather than being preempted.
Generators and Iterators
Coroutines elegantly implement generators and custom iterators for lazy
evaluation and infinite sequences.
-- Simple generatorlocalfunctionrange(from, to, step)
step = step or1returncoroutine.wrap(function()for i = from, to, step docoroutine.yield(i)
endend)
endfor n in range(1, 10, 2) doprint(n) -- 1, 3, 5, 7, 9end-- Infinite generatorlocalfunctionnaturals()returncoroutine.wrap(function()local n = 1whiletruedocoroutine.yield(n)
n = n + 1endend)
endlocal gen = naturals()
print(gen()) -- 1print(gen()) -- 2print(gen()) -- 3-- Fibonacci generatorlocalfunctionfibonacci()returncoroutine.wrap(function()local a, b = 0, 1whiletruedocoroutine.yield(a)
a, b = b, a + b
endend)
endlocal fib = fibonacci()
for i = 1, 10doprint(fib())
end-- Filter generatorlocalfunctionfilter(gen, predicate)returncoroutine.wrap(function()for value in gen doif predicate(value) thencoroutine.yield(value)
endendend)
endlocal evens = filter(range(1, 20), function(n)return n % 2 == 0end)
for n in evens doprint(n) -- 2, 4, 6, 8, 10, 12, 14, 16, 18, 20end-- Map generatorlocalfunctionmap(gen, transform)returncoroutine.wrap(function()for value in gen docoroutine.yield(transform(value))
endend)
endlocal squared = map(range(1, 5), function(n)return n * n end)
for n in squared doprint(n) -- 1, 4, 9, 16, 25end-- Take generator (limit results)localfunctiontake(gen, n)returncoroutine.wrap(function()local count = 0for value in gen doif count >= n thenbreakendcoroutine.yield(value)
count = count + 1endend)
endlocal first5 = take(naturals(), 5)
for n in first5 doprint(n) -- 1, 2, 3, 4, 5end-- Chain generatorslocalfunctionchain(...)local generators = {...}
returncoroutine.wrap(function()for _, gen inipairs(generators) dofor value in gen docoroutine.yield(value)
endendend)
endlocal combined = chain(range(1, 3), range(10, 12))
for n in combined doprint(n) -- 1, 2, 3, 10, 11, 12end-- Zip generatorslocalfunctionzip(gen1, gen2)returncoroutine.wrap(function()whiletruedolocal v1 = gen1()
local v2 = gen2()
if v1 == nilor v2 == nilthenbreakendcoroutine.yield(v1, v2)
endend)
endlocal letters = coroutine.wrap(function()for c instring.gmatch("abc", ".") docoroutine.yield(c)
endend)
local zipped = zip(range(1, 3), letters)
for num, letter in zipped doprint(num, letter) -- 1 a, 2 b, 3 cend-- Permutation generatorlocalfunctionpermute(array)returncoroutine.wrap(function()localfunctionperm(arr, n)
n = n or #arr
if n == 1thencoroutine.yield(arr)
elsefor i = 1, n do
arr[n], arr[i] = arr[i], arr[n]
perm(arr, n - 1)
arr[n], arr[i] = arr[i], arr[n]
endendendlocal copy = {}
for i, v inipairs(array) do
copy[i] = v
end
perm(copy)
end)
endfor perm in permute({1, 2, 3}) doprint(table.concat(perm, ", "))
end-- File line iteratorlocalfunctionlines(filename)returncoroutine.wrap(function()local file = io.open(filename, "r")
ifnot file thenreturnendfor line in file:lines() docoroutine.yield(line)
end
file:close()
end)
end
Generators enable lazy evaluation and infinite sequences with clean, readable
syntax.
Producer-Consumer Pattern
Coroutines elegantly implement producer-consumer patterns without explicit
queues or callbacks.
-- Basic producer-consumerlocalfunctionproducer()returncoroutine.create(function()for i = 1, 10doprint("Producing " .. i)
coroutine.yield(i)
endend)
endlocalfunctionconsumer(prod)whilecoroutine.status(prod) ~= "dead"dolocal success, value = coroutine.resume(prod)
if success and value thenprint("Consuming " .. value)
endendendlocal prod = producer()
consumer(prod)
-- Filtered producer-consumerlocalfunctionfiltered_producer(filter_fn)returncoroutine.create(function()for i = 1, 20doif filter_fn(i) thencoroutine.yield(i)
endendend)
endlocal even_prod = filtered_producer(function(n)return n % 2 == 0end)
consumer(even_prod)
-- Multiple consumerslocalfunctionmulti_consumer(prod, num_consumers)local consumers = {}
for i = 1, num_consumers do
consumers[i] = coroutine.create(function()whiletruedolocal success, value = coroutine.resume(prod)
ifnot success or value == nilthenbreakendprint(string.format("Consumer %d got %d", i, value))
coroutine.yield()
endend)
end-- Round-robin schedulinglocal active = truewhile active do
active = falsefor _, consumer inipairs(consumers) doifcoroutine.status(consumer) ~= "dead"thencoroutine.resume(consumer)
active = trueendendendend-- Pipeline patternlocalfunctionpipeline(...)local stages = {...}
returnfunction(input)local current = inputfor _, stage inipairs(stages) dolocal co = coroutine.create(stage)
local results = {}
for value in current dolocal success, result = coroutine.resume(co, value)
if success and result thentable.insert(results, result)
endend-- Convert results to generator
current = coroutine.wrap(function()for _, v inipairs(results) docoroutine.yield(v)
endend)
endreturn current
endend-- Data processing pipelinelocalfunctiondouble(n)coroutine.yield(n * 2)
endlocalfunctionadd_ten(n)coroutine.yield(n + 10)
endlocal process = pipeline(double, add_ten)
local result = process(range(1, 5))
for n in result doprint(n) -- 12, 14, 16, 18, 20end-- Task scheduler with prioritieslocal Scheduler = {}
functionScheduler.new()return {
tasks = {},
current = 1
}
endfunctionScheduler.add(scheduler, priority, task_fn)table.insert(scheduler.tasks, {
priority = priority,
coroutine = coroutine.create(task_fn)
})
table.sort(scheduler.tasks, function(a, b)return a.priority > b.priority
end)
endfunctionScheduler.run(scheduler)while #scheduler.tasks > 0dolocal task = scheduler.tasks[1]
local success, result = coroutine.resume(task.coroutine)
ifcoroutine.status(task.coroutine) == "dead"thentable.remove(scheduler.tasks, 1)
else-- Move to end for round-robintable.remove(scheduler.tasks, 1)
table.insert(scheduler.tasks, task)
endendend-- Usagelocal sched = Scheduler.new()
Scheduler.add(sched, 1, function()for i = 1, 3doprint("Low priority task " .. i)
coroutine.yield()
endend)
Scheduler.add(sched, 10, function()for i = 1, 3doprint("High priority task " .. i)
coroutine.yield()
endend)
Scheduler.run(sched)
Producer-consumer patterns with coroutines eliminate callback complexity and
provide clear data flow.
Asynchronous Patterns
Coroutines enable asynchronous I/O patterns without callbacks, providing
sequential-looking code for async operations.