lua-users home
lua-l archive

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

On 14/01/15 13:28, Roberto Ierusalimschy wrote:
On 14/01/15 10:22, Roberto Ierusalimschy wrote:
(Sometimes I wonder whether it would be better if the
"nil-message" paradigm was "false-message" instead...)
I don't believe that. False is  a value that is a perfectly valid
return from a function. Nil is the absence of value, so returning
nil means the function could not produce a result. In other words, I
need to distinguish between a functio returning the value false, and
a function unable to return a value.
The problem is the message after the nil. How can you have a second
result when you don't have a first one? (This is strongly related
to the problem of holes in lists.)

If the function was just returning nothing, that would be ok. But
in fact it is returning an error indicator followed by the error
message. To mix an error indicator with an absent value is what bothers

I'm not sure I understand what you're saying, but perhaps it is related to the following. Once I had a function that had to parse a string, which could carry some of several messages inside. Paraphrasing my implementation, written a long ago:

local m1,m2,m3,m4 = parse("m1=a m3=b")

So, after calling parse, some of the returns would have a value and others would be nil. Today, I believe this api is ugly, and I would rewrite it as returning a single table. Perhaps because my first functions were in Pascal, and maths before that, for me functions return a single "thing". In Lua this "thing" could be expressed as a value, or as set of values (...). But nil is not a value. And if a application has some other meaning for nil besides "absence of value", perhaps something from the application domain, then I think said application is badly designed. In that sense, in application domain, nil is not a "perfectly valid return"

So, if the first return is nil, you should be able to safely assume that there won't be anything of interest after that. Except an explanation.

Moreover, some functions can return 'nil' as a "perfectly valid return"
too. (That is why 'pcall' has an explicit first boolean result.) On the
other hand, if you go through the libraries, you will see that most
(all?) functions that return nil-message return only a very specific
type as a correct result, so they cannot return 'false'. Actually, when
we use the common idiom 'assert(foo(...))' to change an error indicator
to an error, we are already assuming that the function cannot return

-- Roberto

Even if what you say about library calls is true, the use pattern must hold true trough all the users codebase, and there must be a lot of use cases for a boolean returns (operators, datastructures...).

pcall() is a very special function, because it's sort of meta. It doesn't talk business logic so to say, but language constructs (functions as such). So the success indicator is needed because it is separated and independent from the invoked function's semantics.

Nevertheless, what you say on assert() is true... Another stumbling block for me is the difference between returning a nil, and not returning anything (like in select('#', ...)==0)