lua-users home
lua-l archive

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



On 21-Oct-05, at 12:24 PM, Roberto Ierusalimschy wrote:

We would like to add Mike Pall's extension on gsub (to work with tables)
still in 5.1.

That's great! It would be very useful.

However, to avoid inconsistencies, it would be better
if function-call and table-lookup results were interpreted the same
way.

That makes sense.

That means to change the meaning of functions returning nil (or
nothing) from "the replacement string is the empty string" to "makes no
replacement".

It seems a bit odd that nil and false would have such radically different meanings. I currently frequently use idioms like

  function(capture) return <some condition> and <some string value> end

without worrying about whether <some condition> returns nil or false as its false value.

I also find the "delete on nil" behaviour convenient, because it makes it convenient to check the resulting string for lexical errors. For example, the following nicely captures keyword=value pairs from a string:

string.gsub(kwlist, '(%a%w*)="([^"]*)"', function(k, v) args[k] = v end)

but it will silently skip over errors. Changing it to this:

  assert(string.find(string.gsub(....), "^%s*$"), "Garbage in kwlist")

is a simple (if perhaps non-obvious) way of checking the result, since only those characters which didn't match are still in the result (given the function's implicit return of nothing).

Using gsub as an iterator was perhaps more common before we had gfind (now gmatch, I understand). But gmatch does not provide any easy way to do the above "completeness" check.

In many ways it would be better to use a true result to mean "keep the original" but I understand the pragmatism of using nil as a table entry -- i.e., if you don't find it, don't replace it. The argument is much less strong for functions; in particular, many functions indifferently return nil and false to mean the same thing, whereas "the absence of a key" and "a key with a definite boolean false value" are semantically quite different in the context of tables.

I don't think many programs have functions returning nil when they
want an empty replacement string, but anyway that would be a small
incompatibility from 5.1 alpha to beta (and final).

It is possible that I am the only person who uses this idiom. I do like Mike's patch and so I am prepared to go through my code and try to find the instances of it. But I wonder if it is really necessary to abandon a somewhat useful idiom.

(Also, it seems more consistent if results different from nil/false
and string/numbers raise errors, instead of being ignored like
they are now. Again, I don't think many programs have gsubs with
functions returning weird values, but again that would be a small
incompatibility.)

It would certainly make sense to flag inappropriate results as errors.

Continuing on the theme of functions, I wonder if it would make sense (and be more consistent) if the replacement table could be a table of functions, and not just of strings; that is, if the table value is a function, then that is the function which is called. I realize that this could be done with a function in the first place, but then so could the table substitution.