• Subject: Re: Arithmetic on strings
• From: Rena <hyperhacker@...>
• Date: Wed, 13 Jun 2012 16:03:52 -0600

```On Wed, Jun 13, 2012 at 3:50 PM, Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
>> interesting, so what is the trick for
>>
>> local t = { 1, 2, "test", true }
>>
>> print(table.concat(t))
>
> There is no trick in this case. As I said, those cases should be
> solved in an individual basis. Whether or not table.concat accepts
> other types is somewhat independent of whether format'%s' accepts
> other types, etc. Therefore, each function decides what coercions
> to apply to its arguments. My point is that what each function does
> can be independent of the coercions done by the language.
>
> (It would be interesting if table.concat followed the semantics of '..',
> but that already is not the case.)
>
> -- Roberto
>

One place that automatic coercion has bit me is in writing C functions
that accept different types of arguments. For example an "open file"
function that accepts a path, a numeric file descriptor, or a table
containing those and some other information.

So the logic looks like:
if(lua_isstring(L, 1)) /* we have a path */
else if(lua_isnumber(L, 1)) /* we have an FD */

Who sees the problem there? lua_isstring() will return *true* for
numbers, because lua_tostring() will silently convert them. So the FD
path is never reached. OK, simple enough, reverse the check:

if(lua_isnumber(L, 1)) /* we have an FD */
else if(lua_isstring(L, 1)) /* we have a path */

Should be fine now, right? Still, not quite, because lua_isnumber()
and lua_tonumber()/lua_tointeger() do the same conversion. That means
it's no longer possible to open a file with a purely numeric name.

Then the table iteration issue people have mentioned; I've been
careful to avoid it (at the expense of some extra stack operations
inside every loop), but who knows how many have been bitten there...

The one place it is nice is in concatenation, when I can write code like:
assert(things > 3, "only have " .. things .. " things, need at least 3")
not having to put a tostring() call in there helps make the code