Functions Without Returns

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Functions Without Returns

Ken Smith-2
I ran into a bit of Lua behavior I'd like to discuss in the forum.
Consider this example.  (Tested under Lua 5.1.3 on Mac OS X.)

cat<<EOF>test.lua
function nothing()
end

local result = nothing()

print(tostring(result))

print(tostring(nothing()))
EOF

The first print yields, "nil", whereas the second one causes the
following error.

lua: test.lua:8: bad argument #1 to 'tostring' (value expected)
stack traceback:
	[C]: in function 'tostring'
	test.lua:8: in main chunk
	[C]: ?

The manual is clear that a function "without...a return
statement...returns with no results" (2.5.9).  But then the discussion
of nil mentions that it "usually represents the absence of a useful
value" (2.2).

My expectation was that a function with no return would return no
results in the form of a nil.  Granted there is a conundrum, if a
function returns nil, then it returns a result.

The way I see it, a function without a return returns no values which
introduces another, distinct nil concept into the Lua runtime.  There
is nil, which is a placeholder value meaning, "different from all
other values", then there is true nil as is generated by a function
with no return which is the true absence of any value.

Clearly, the workarounds are unobtrusive and numerous.  However, I
find this curious, so I'd like to hear a few more opinions on this
issue.  Should a function with no return statement return 'nil', or
nothing?  Are they different semantically?

   Ken Smith

Reply | Threaded
Open this post in threaded view
|

Re: Functions Without Returns

John Calsbeek
How about the semantics of the following?

function multireturn(num)
     if num == 0
        return
     elseif num == 1
        return 1
     elseif num == 2
        return 1, 2
    end
end

function multiparam(...)
    print(select("#", ..))
end

multiparam(multireturn(0))

That would print 1, if an empty return is coerced to a nil return.

-John

On Jan 25, 2008, at 12:16 PM, Ken Smith wrote:

I ran into a bit of Lua behavior I'd like to discuss in the forum.
Consider this example.  (Tested under Lua 5.1.3 on Mac OS X.)

cat<<EOF>test.lua
function nothing()
end

local result = nothing()

print(tostring(result))

print(tostring(nothing()))
EOF

The first print yields, "nil", whereas the second one causes the
following error.

lua: test.lua:8: bad argument #1 to 'tostring' (value expected)
stack traceback:
	[C]: in function 'tostring'
	test.lua:8: in main chunk
	[C]: ?

The manual is clear that a function "without...a return
statement...returns with no results" (2.5.9).  But then the discussion
of nil mentions that it "usually represents the absence of a useful
value" (2.2).

My expectation was that a function with no return would return no
results in the form of a nil.  Granted there is a conundrum, if a
function returns nil, then it returns a result.

The way I see it, a function without a return returns no values which
introduces another, distinct nil concept into the Lua runtime.  There
is nil, which is a placeholder value meaning, "different from all
other values", then there is true nil as is generated by a function
with no return which is the true absence of any value.

Clearly, the workarounds are unobtrusive and numerous.  However, I
find this curious, so I'd like to hear a few more opinions on this
issue.  Should a function with no return statement return 'nil', or
nothing?  Are they different semantically?

Reply | Threaded
Open this post in threaded view
|

Re: Functions Without Returns

Kristofer Karlsson
In reply to this post by Ken Smith-2
In the first case, you try to store zero values "nothing()" into one
variable "local result".
The lua behaviour is then to expand the return value list with enough
nils to fill up all the variables.

This is the same case as with:
function foo()
  return 1
end

local x, y = foo()
-- here x is 1 and y is nil

On Jan 25, 2008 7:16 PM, Ken Smith <[hidden email]> wrote:
> I ran into a bit of Lua behavior I'd like to discuss in the forum.
> Consider this example.  (Tested under Lua 5.1.3 on Mac OS X.)
>
> cat<<EOF>test.lua
> function nothing()
> end
>
> local result = nothing()
>
> print(tostring(result))
>
> print(tostring(nothing()))
> EOF
>
> The first print yields, "nil", whereas the second one causes the
> following error.
>
> lua: test.lua:8: bad argument #1 to 'tostring' (value expected)
> stack traceback:
>         [C]: in function 'tostring'
>         test.lua:8: in main chunk
>         [C]: ?
>
> The manual is clear that a function "without...a return
> statement...returns with no results" (2.5.9).  But then the discussion
> of nil mentions that it "usually represents the absence of a useful
> value" (2.2).
>
> My expectation was that a function with no return would return no
> results in the form of a nil.  Granted there is a conundrum, if a
> function returns nil, then it returns a result.
>
> The way I see it, a function without a return returns no values which
> introduces another, distinct nil concept into the Lua runtime.  There
> is nil, which is a placeholder value meaning, "different from all
> other values", then there is true nil as is generated by a function
> with no return which is the true absence of any value.
>
> Clearly, the workarounds are unobtrusive and numerous.  However, I
> find this curious, so I'd like to hear a few more opinions on this
> issue.  Should a function with no return statement return 'nil', or
> nothing?  Are they different semantically?
>
>    Ken Smith
>

Reply | Threaded
Open this post in threaded view
|

Re: Functions Without Returns

Javier Guerra Giraldez
In reply to this post by Ken Smith-2
On 1/25/08, Ken Smith <[hidden email]> wrote:
> issue.  Should a function with no return statement return 'nil', or
> nothing?  Are they different semantically?

yes they are.

i think in this case the issue is if tostring() should return a value
even when it gets no parameter?

OTOH, the 'real best' approach is to document all.  in your example:

- nothing() could return no value
- tostring() gets exactly one paramenter

therefore,   tostring(nothing()) isn't safe according to the
documentation, you'd be expected to write tostring(nothing() or nil)

-- 
Javier

Reply | Threaded
Open this post in threaded view
|

RE: Functions Without Returns

Jerome Vuarand-2
Javier Guerra wrote:
> - nothing() could return no value
> - tostring() gets exactly one paramenter
> 
> therefore,   tostring(nothing()) isn't safe according to the
> documentation, you'd be expected to write tostring(nothing() or nil)

Alternatively you can simply add an extra pair of parenthesis :
tostring((nothing()))


Reply | Threaded
Open this post in threaded view
|

Re: Functions Without Returns

Matthew Paul Del Buono
In reply to this post by Ken Smith-2
The reason is quite simple actually. Lua normalizes returns. If a function does not return enough values to fill all of the variables, then those variables get filled with nil:

function foo()
  return 1,2;
end

local a,b,c = foo();

a and b will be 1 and 2, respectively, as expected, but c will be nil. It can't be "nothing" ... it's a variable.

You're encountering something similar:

function foo()
   return; 
end

local bar = foo();
print(tostring(bar))
print(tostring(foo()))

The first prints nil, because bar IS nil. A variable can't be nothing. foo(), however, returns nothing. When you run tostring() on it, nothing is passed to it. It is the same as doing tostring(), which is illegal. That is why the error arises.

-- Matthew P. Del Buono a.k.a. Shirik