Consider this test case.
function test()
return 1, 2, 3
end
-- OK: prints 4 1 2 3
print (4, test())
-- NOT OK: prints 1 4
print (test(), 4)
Why do values returned from a function in a function call expression (already pushed to stack) are discarded and narrowed down to a single one, when combined with another value on the right. While at the same time, nothing is discarded when combined with another value on the left.
Is it even possible to extend a set of values returned from a function call to the right, without resorting to table. Because tables have their own issues like counting size by first nil. While nil is a totally reasonable value to pass as function argument as well as return from function, along with some other values.
Subsequently, it's not even possible to do things like this:
local ret = {test()}
-- NOT OK: still prints 1 4
print (table.unpack(ret), 4)
The design of Lua VM resulted in allowing any number of return values only for function call at the end of the parameter list. This behavior is described in the Lua manual section 3.4.12 – Lists of expressions, multiple results, and adjustment.
Lua VM is known to be register based, unlike stack based VMs, its instructions require specifying registers. For example, calling print (test(), 4) involves the following steps:
print function into R0test function into R1test function and save the return value into R14 into R2print functionIt can be seen that if the test function is allowed to return any number of values, the arrangement of these return values becomes a problem. You can choose:
Load the number 4 into R2 and save the return value of test to R3, R4, ..., but when calling the print function, you have to consider the issue of parameter order, which is obviously too complicated.
Save the return value of test to R1, R2, ..., and then load the number 4 to a dynamic location based on the number of return values (eq to PUSH), but this turns Lua into a stack based VM.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With