lua-users home
lua-l archive

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

On Wed, Jan 14, 2015 at 5:40 PM, Tom Sutcliffe <> wrote:

> Yes, me too. I've always been happy with how Lua handles nil and errors. You
> can always wrap your call in an assert() to convert a nil result to an
> error, if that fits your code flow/style better, but it's much less
> convenient to convert an error to a nil. (Python's insistence in trying to
> make everything use errors just plain aggrevates me). My background is from

How is `assert` harder and `pcall` easier? Perhaps there are many
times when you want to *silently* ignore a `nil, error_msg` return
value? If so, that would make sense. If not, then you must handle the
`nil, err` any way, correct?

When you are handling this sort of return value, I assume that you
typically handle it at the point of the return, as Javier states. If
this is so, is there a "most common" way that you find yourself
handling it? For me, that was typically something like:

if retval == nil then return nil, second_value end

Which, in turn, meant that the caller needed to handle it, right on
back to some main message handler, which would turn this into a reply.
And so, I can use assert, but assert is not quite the same. When I'm
debugging, I appreciate having the stack trace start at the point of
the error, not at the point that the function returned. Using `assert`
means that I need to change the code in some way, in order to retrieve

> environments where setjmp/longjmp were considered expensive operations so I
> may be a little biased there, I suppose.

I assume (haven't needed to test) that an error is much slower than a
`nil, string` return, but there aren't many cases where I expect to
fail enough for that to matter, and in that case, `nil, string` makes
more sense.

I hope that people generally agree that ingrained behavior /
preferences that come from different languages are not reasons alone
to prefer one way over another. There should be good reasons to do one
way over the other. I'm reading these responses and I'm looking for
those good reasons and beyond preference (which is a fine enough
reason), I'm not understanding one.

> As for making errors a proper type,
> again I like the fact that Lua doesn't prescribe a particular type, and that
> if you want to you can call error() with pretty much anything. It means you
> have great flexibility in how you use errors, and having the standard
> libraries not use them at all means they will not conflict with whatever
> system you pick.
> (Fun fact: error(nil) doesn't print an error message if you run it in the
> interpreter even though xpcall(error, debug.traceback, nil) does return nil
> plus a stacktrace in the second result so you'd expect it should print
> something.
> Sllightly more understandable fun fact: calling error with a non-string
> means you won't get stack traces out of the standard xpcall(fn,
> debug.traceback, ...) pattern and you have to roll something a little more
> sophisticated.)

And this is what I do. Because I'm using `error` I can set a global
`_DEBUG` flag, which adds the stack trace to the message. I've also
included an error number, which then looks up the error text in a
table, making it easier to parse the errors that do need to handle. No
need for an error type and adding `__tostring` to the message makes it
print as normal error.

> Lua's slight wrinkle with nil and false both being "falsey" makes far more
> sense than the equivalent rules in say Javascript or Python (I do
> occasionally trip myself up with zero being truthy in Lua but falsey in C,
> but on balance I wouldn't want it to be falsey in Lua, it would be too
> messy. I'm just too used to C sometimes.). Even the distinction of none vs
> nil in the C API never bothered me, since it so rarely matters anyway.
> Returning non-nil values following a nil never seemed illogical to me - I
> don't find the arguments against such a construct to be that compelling. The
> only thing I think is a bit messy is integer-indexed tables with nil
> 'holes'. Careful wording around 'well-formedness' in the table documentation
> gets you so far, but I never did figure how for instance that was supposed
> to work with the __ipairs metamethod. Ah: I see that is deprecated in 5.3 -
> that simplifies matters! So I don't think I have any real compliants there
> either.
> In short, please don't change anything in this area, I like it fine just how
> it is :-)
> Cheers,
> Tom

 I agree with this. No need to change anything.

I was thinking more along the lines of how Lua libraries handle "soft"
errors and with conventions around errors, generally. `nil, string` is
an idiom that happily emerges from the language, without anything
within the language that gives it permission to exist as an "error
condition". Someone can just as easily design an API where this was
not error and in a few cases, this would even make sense.

It's that ambiguity that sours me on it. I think it's a potentially
hairy thing for an api developer to be deciding between

assert: "the program is not correct"
error: "you gave me something bad or something unexpected happened and
I'm quitting"
nil, string: "something that's normal happened that prevented me from
carrying out your request"

In production code, I would ignore the first, deal with the second and
then deal with the third, too. I can't see that being easier.

Since switching to errors, in my 30-ish file project I call `pcall` 5
times. Banishing nil, error_msg didn't have much impact on that number
because there are not that many times that actually I do anything
fancy with an error.

Hopefully there is a little more to this than just opinion and style
and that's why I think that this is a conversation worth having. As I
mentioned, I'm happy to keep doing what I'm doing while everyone else
picks the "Lua Way".