Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it not possible to extend a function call expression returning multiple values with another value on the right in Lua

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)
like image 336
GreenScape Avatar asked Dec 14 '25 03:12

GreenScape


1 Answers

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:

  1. Load the print function into R0
  2. Load the test function into R1
  3. Call the test function and save the return value into R1
  4. Load the number 4 into R2
  5. Call the print function

It 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:

  1. 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.

  2. 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.

like image 181
shingo Avatar answered Dec 16 '25 04:12

shingo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!