Manual:Scribunto/Lua reference manual

Assignments
The variable-list is a comma-separated list of variables; the expression-list is a comma-separated list of one or more expressions. All expressions are evaluated before any assignments are performed, so  will swap the values of a and b.


 * Warning
 * The comma in Lua does not behave at all like in other common languages (such as C, C++, or Java), when they are using it either as an operator in expressions, or as a separator for the declaration of variables and function parameters or within the initializers of declared variables, or in the parameter list of function calls. Its use in Lua assignments does not create a "comma expression" (is which valid as an expression statement in C or C++). The assignments in Lua are not themselves valid expressions (usable in subexpressions), they are only valid as statements within a block.
 * Also the number of expressions in the expression-list in Lua does not need to match the number of variables in the variable-list. So in the following assignments:
 * , a will be assigned the value 2, and b will be assigned the value nil (this may seem counter-intuitive for programmers using other languages).
 * , all variables in the variable-list will be assigned the value nil (this is explicit for a and implicit for b ).
 * (common in Lua), a will be asssigned the first returned value, and b will be assigned the second returned value if there's one, or nil otherwise.
 * , b may not necessarily be assigned the value 2 if  returns more than one value or a variable number of values: in that case the first returned value will be assigned to a, the second returned value will be assigned to b , the remaining returned values and 2 will be discarded; if the function does not return any value, a will be assigned 2 and b will be assigned nil.
 * Internally, when there's more than one variable in the variable-list, Lua will create a temporary number-indexed array (with a fixed size determined by the number of variables to assign), in which it will successively append the returned values of each expression in the expression-list (they are all evaluated, from left to right). Then Lua will assign each variable of the variable-list from the temporary number-indexed array; if there's not enough values in the temporary number-indexed array, the remaining variables are assigned the value nil ; if there's more values in the temporary number-indexed array than variables in the variables-list, these values in excess are ignored. Finally the temporary number-indexed array is discarded.
 * This internal process is also used in every other Lua statements that use an expression-list, including the initialisation values in local variable declarations, or the bounding values of the  control statement, or for creating the list of values that will be passed as effective parameters in function calls and then initializing the parameter variables within each called function during its evaluation.

To avoid this separation of values returned by a function (a feature expected by some common Lua functions such as pairs, ipairs or next), that function should explictly return a single array containing all values, instead of a list of expressions, and a reference to that array will be assigned to a single variable. The alternative is to create a new array containing the returned values:, and then access its members by their number index (the first value returned by the function call is in   in this example).

When the expression-list contains a static number of expressions, i.e. when they are not the result of calling some function that may return multiple values or a variable number of values, and these expressions do not depend (during their evaluation) on the current value of variables before their assignment, it may be preferable to separate the statements that will assign individual expressions to the relevant variable(s), in order to get more predictable results (the assignments still continue working with the number of values they expect, even if functions are modified later to return more values than what for which they were initially designed).


 * So  is not recommended (unless you are sure that   will always return one value), and should preferably be written as   or as   where the parentheses surrounding both expressions have the effect of discarding all values except the first one returned by each function call (if a function call does not return any value, the evaluation of the expression with surrounding parentheses will give nil ).
 * But the code  is perfectly safe, just as  : the operators in numeric expressions keep only the first value returned by their operands, and if an operand is a function call that does not return any value, the value of that operand will be nil.
 * The only expression that is not a function call and that keeps multiple values during its evaluation is the special varargs expression, valid only within the scope of a function declared with a varargs parameter (if you combine the varargs with other operations or within parentheses, this will force it to be its first value, or nil if the parameter list is empty).
 * So the assignment  depends on the length of the varargs list: a will be assigned the first value in the varargs and b will be assigned the value 2 only if the varargs list contains exactly one parameter value; if the varargs list is empty, a will be assigned the value 2 and b will be assigned the value nil ; if the varargs list contains two or more parameter values, then a and b will be assigned the first two values in the varargs list. The only way to keep all values in the varargs list is to initialize a new array to contain them: , or to use it in other statements that accept an expression list:   (note the surrounding parentheses to also force the values returned by the function call to only one value).