lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 11/09/2011 17.02, Florian Weimer wrote:
* Lorenzo Donati:

(1) is it safe to rely on such behaviour? I.e. is it intentional or is
it only an implementation detail that may change at any time, even
with minor releases of Lua? Lua 5.2 still complies, but haven't found
a clear reference to this behaviour in the manual.

It's a result of this:

| If an expression is used as the last (or the only) element of a list
| of expressions, then no adjustment is made (unless the call is
| enclosed in parentheses).

(Section 2.5)

And this:

| Otherwise, index must be the string "#", and select returns the
| total number of extra arguments it received.

(Section 5.1)


Thanks, but I did read that. They explain why select returns 0. That was clear. What was not clearly defined IMHO was the semantics of the return statement.

The two excerpts I cited in the initial message only *hints* that a function can return no value. The manual explicitly cite the case when there is no return statement. But a statement with an empty expression list is not explicitly covered. The manual says:

"Functions and chunks can return more than one value..."

which again tells nothing about the case of *no* value. The "no return value" can only be inferred by common sense, but it is not clearly defined.

Other languages are more explicit in defining what the meaning of "return" is. IIRC C/C++/Java state that the meaning is the same as assignment, but here this is of no help, since obviously it is not the same for Lua since:

function f() return end
function g() return nil end

cannot be told apart using assignment:

local x = f()  --> x == nil
local x = g()  --> x == nil

so it seems that only "select" has the notion of "no return value vs. nil return value".

Therefore my doubt remains about whether "return" and "return nil" are semantically different also from a language definition POV, or the behaviour detected by "select" is only a byproduct of the current implementation. Moreover, being "select" a library function and not part of the language, from a formal POV its definition and behaviour should not influence the language meaning (IIRC one could even avoid loading the base library when using the C API, so select could even be missing).

Maybe I'm missing something, but IMHO the manual is not clear about it.



(2) assuming that (1) is intentional and stable, I'd like to pass a
function (call it "func") to an higher order function that will call
it many times and do different things according to whether func
returned no values instead of only nil values.

function higher( func )
   local nrets
   local function helper( ... )
     nrets = select( '#', ... )
     return ...
   end

   local ret1, ret2 = helper( func() )
   if nrets == 0 then
     print "func returned no values"
   else
     print "func returned something:"
     print( ret1, ret2 )
   end
end

I think you should put your logic into the helper function itself.
The result will be a bit simpler, and you can perhaps avoid creating
closures.




Good idea! Thanks!
I'll try that and see if it helps.

Cheers!
-- Lorenzo