lua-users home
lua-l archive

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




On Monday, January 6, 2014, Josh Haberman wrote:
I wanted to hear people's opinions about implicit conversion in Lua.

Say I am exposing to Lua a strongly-typed data structure. It behaves
like a table in many ways, but the set of keys is predefined and each
key as a pre-determined type. So for example:

-- Data structure is: name (string), age (integer)

struct.name = "James"
struct.age = 22

-- Throws "no such field"
struct.doesnt_exist = 5

-- Throws "can't assign string to integer field"
struct.age = "XYZ"

So my first question is, does it seem Lua-like to allow implicit
string <-> integer conversion when it is safe?

-- Auto-convert to "12345" or throw an error?
struct.name = 12345

-- Auto-convert to 22 or throw an error?
struct.age = "22"

Secondly, what is the Lua-like way to handle overflow and truncation?

-- Throw an error or truncate? (assume age is uint32_t)
struct.age = <UINT32_MAX + 1>

-- Throw an error or silently truncate to 22?
struct.age = 22.12345

It appears that luaL_checkinteger() in both Lua 5.2 and Lua 5.3 work1
will silently truncate in this latter case.

Pros of auto conversion/truncation:
- "do what I mean", less typing

Cons of auto conversion/truncation:
- can lead to silent data loss/corruption
- throwing errors might help find bugs sooner

Thoughts? What is the "Lua way" here?


I agree with everything said this far. I'll add:

Having C code throw an error if I add a non-existent field is very un-Lua like. In fact, it might be you that wants to extend the struct and finds that it's easier to build the nice interface in Lua, instead of C. Just ignore the fields that you aren't using. 

If the data type is unlikely to overflow (age is a persons age, for example), then I wouldn't typically over flow check. I *might* check to see if luanumber is *very close* to truncated int + 1, in order to check float issues. But I only do this if it seems plausible that the result could come from division. 

I tend to coerce strings to ints explicitly, even though Lua does it automatically. [1]

Too much checking will lead you down a productivity rat hole, for not much value. For me, it came from my own inexperience with dynamic languages and the most effective ways in which to gain from their strengths, while truly checking and trapping bugs that are worth trapping. 

I've now decided that for every check that I use to do, I'm better off with a good test on the API. I don't do anything about errors that the user might commit when Lua will barf on the input, without my help. 

[1] You can get too clever in the other direction, too: if you expect string, is table really an error? What if __tostring was defined on the table's metatable?
Another helpful rule (for me) is: if the error happened in lua, always give the error in the context of Lua. We have a C programmer that loves Visual Studio's debugger. The asserts he throws in C are always a problem for me, when I made the mistake in Lua. This is probably obvious and there are times when it makes sense to do so (debugging your C API). I mention it because it came up for us.

-Andrew