lua-users home
lua-l archive

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


On Wed, Dec 1, 2010 at 6:53 PM, Lorenzo Donati
<lorenzodonatibz@interfree.it> wrote:
> 1. I discovered "late in the game" that the most efficient way to append an
> item to an array was
> a[#a+1]=item
> and not
> table.insert(a,item)

This idiom looks good in mailing list examples where tables have
one-letter names, but in actual production code, I often find myself
doing stuff like this:

   table.insert(responses.handlers[selected].messages, msg)

which clearly shows the intent of what I'm doing. Doing this like:

   responses.handlers[selected].messages[#responses.handlers[selected].messages
+ 1] = msg

hurts readability and maintainability. Of course, the obvious
suggestion would be to do something like

   local selected_msgs = responses.handlers[selected].messages
   selected_msgs[#selected_msgs + 1] = msg

but then this is also longer to write and read than the table.insert
variant (and most of the time I spent to write the above example was
spent thinking up the local variable name -- yes, these things add
up), and most importantly, someone unfamiliar with the code who is
reading it the first time will have one more local variable to keep in
mind when mentally interpreting it. Strictly speaking, this latter
problem can be "solved" by doing

   do
      local m = responses.handlers[selected].messages
      m[#m + 1] = msg -- given the scope is so tiny a one-letter var is okay
   end

But that's of course not a practical thing to do every time one wants
to append to an entry in a data structure.

Sure, there are situations where data structures are walked in stages
and I may end up with my array in a local, so that

   selected_msgs[#selected_msgs + 1] = msg

would be an option. But it doesn't feel right to use two different
idioms to do the exact same thing in different places of the code --
it certainly adds a toll to readers, especially ones unfamiliar with
the language[*]. In any case, the repetition of the variable name is
cumbersome to type and maintain -- a violation of the so-called DRY
principle in micro-scale.

For these reasons, I continue to use table.insert in my code.

Cheers,
-- Hisham

[*] Of course, this is a minor problem compared to explaining the
weird behavior of the # operator. I predict it will be changed to
return the actual number of elements of a table sometime around Lua
7.0 (when the argument that not maintaining a counter saves precious
memory and processing won't be as compelling), and then the Lua
authors will have a fun time telling stories about how they struggled
to explain the behavior of # 'back then' in the manual as being
'"length" between quotes' just like they do now saying they explained
upvalues as being 'kind of like lexical scoping' before they went and
implemented proper lexical scoping. :-)