lua-users home
lua-l archive

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


On Tue, Mar 19, 2013 at 06:07:05PM -0600, William Sumner wrote:
> On Mar 19, 2013, at 5:29 PM, Kevin Martin <kev82@khn.org.uk> wrote:
> 
> > On 19 Mar 2013, at 22:53, William Sumner wrote:
> > 
> > It was meant as a rhetorical question, to ask yourself. However, to comment on your suggestions:
> > 
> > 1) The contains function is clearly a bad idea. How would you implement it?
> > 2) The in operator is better-ish, the first question that comes to mind is how you would modify the C API, as lua_gettable/etc can no longer push nil.
> 
> 1.) If you're asking how it would be implemented in Lua, I should have
> been clear that my suggestion assumes a C function in the built-in table
> library.
> 
> 2.) One solution might be to return success or failure if the element
> exists and is successfully pushed onto the stack:
> 
> int lua_gettable(lua_State *L, int index);
> int lua_getfield(lua_State *L, int index, const char *k);

Lua does a fine job of balancing verboseness and simplicity of its API. Some
languages have a plethora of C APIs which do complex operations, others have
very few operations which require laborious and complex expressions.

One of the things, IMO, which allows Lua's C API to strike a good balance is
that table lookups always push nil. This allows one to write operations
without complex condition trees if one chooses.

> > I guess my main objection is that I don't actually think there's a
> > problem. I don't see the unsafeness. I also don't think you have
> > explained why it is unsafe, only stated that it is unsafe.
> > 
> > 1) nil literally means no-value. Is it not reasonable for a table access
> > to return no-value when there is no value to return?
> 
> The safety issue is that simple typos can cause bugs that aren't detected
> until an error is thrown by something that can't handle the nil--if indeed
> such a something ever encountered. These can be difficult-to-find bugs. If
> there was no need to address this, there wouldn't be user-implemented
> solutions or the static analyzers that the large Lua codebases use. The
> implication of such a change would be that Lua would distinguish between
> elements with nil values and elements that don't exist, which is why I
> realize such a change could only get pushed in a major version update.

Conversely, if an error was always thrown then simple typos would cause an
unexpected assertion. This, too, can be unsafe, causing unexpected output or
behavior.

Perl has `exists', `defined', as well as boolean evaluation for nil'ish
values. I rarely ever see the use of `exists'.

Perl users seem to prefer using the `strict' pragma, which effectively
provides behavior almost identical to throwing an error from the __index
metamethod of the global table in Lua.
 
> > 2) Any attempt to do anything with a nil value yields an error, so if getting the nil value was a mistake as your error is trying to catch, the error will be produced as soon as you try and do anything with the value, see below. Is this so far from you error?
> 
> There could very well be an uncaught nil that propagates through the
> program and is noticed a long time later or not at all.

This is a problem with loose typing in general. Unlike other languages, Lua
addresses it in part by performing fewer implicit conversions than most
other similar languages. And yet this is one of the biggest complaints I get
about Lua; not that errors aren't caught earlier, but that implicit
conversions aren't performed more often. Because Lua doesn't have static
typing, tracking down the source of runtime errors is part of the deal.

> It can also cause other distractions, such as an accidentally created
> sparse array that returns an incorrect value from the length operator.
> This might cause further unexpected program results that could lead the
> user to investigate the wrong parts of the program.

Lua doesn't have a dedicated array type. And sparse arrays have unique
semantics that many languages with proper arrays don't get right, either. So
I'm not sure how much distance you'll get in this case by distinguishing nil
and non-existant.

> > 3) Not handling the case of no-value is definitely an error, but that is
> > bad programming, nothing to do with the language.
> 
> One can't assume all programmers are perfect, especially non-professional
> ones exposed to scripting APIs in games. Certainly, none of us are
> perfect. Otherwise, we'd have no need for compiler errors.
> 
> I find the philosophical defenses given so far unconvincing, with all due
> respect, of course. Lua lets one build many things by hand, but that
> doesn't mean all things must be done by hand, and many things aren't. I'm
> sure Lua's developers have considered this issue in the past, so I was
> curious about the reasons for not handling it; e.g., performance reasons,
> conceptual reasons, or otherwise.

This is conjecture on my part, but I believe the choice to not perform as
many kinds of implicit conversions is one way that Lua chose to address your
general area of concern.