 <p>Lua cannot magically give the original arguments new values. They might not even be on the stack anymore, depending on optimizations. Furthermore, there's no indication where the code was when it yielded, so it may not be able to see those arguments anymore. For example, if the coroutine called a function, that new function can't see the arguments passed into the old one.</p> <p><code>coroutine.yield()</code> returns the arguments passed to the <code>resume</code> call that continues the coroutine, so that the site of the yield call can handle parameters as it so desires. It allows the code doing the resuming to communicate with the specific code doing the yielding. <code>yield()</code> passes its arguments as return values from <code>resume</code>, and <code>resume</code> passes its arguments as return values to <code>yield</code>. This sets up a pathway of communication.</p> <p>You can't do that in any other way. Certainly not by modifying arguments that may not be visible from the <code>yield</code> site. It's simple, elegant, and makes sense.</p> <p>Also, it's considered exceedingly rude to go poking at someone's values. Especially a function already in operation. Remember: arguments are just local variables filled with values. The user shouldn't expect the contents of those variables to change unless it changes them itself. They're <code>local</code> variables, after all. They can only be changed locally; hence the name.</p>