lua-users home
lua-l archive

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


Maybe something like this:

Dear Lua newbie,

we understand your question and sympathize with you. Does your table maybe have 'holes'? By adding nil to it or skipping keys?

Please note that # is not defined for 'tables with holes'. It is not (!) defined as the "length" of the table, when the table has holes. There are good reasons for this.

If you look closely, the docs warn you to only use # on tables that have no holes. In all likeliness, you got confused, because your tables have holes and the result of # can then be sth. else than you might have expected. As Roberto points out:

"There is no good *meaning* for #t when t has holes. What should be the results
of the following expressions?

  #{[1000] = 1}
  #{1, nil, 3, 4, 5, 6}
  #{1, 2, nil, 4}
  #{[4] = 4, 1, 2}
  #{1, 2, 3, nil, 4, nil, nil}
  #{1, 2, 3; x = 4}
  t = {1, 2, 3, 4}; t[4] = nil; print(#t)
  t = {1, 2, 3};    t[4] = nil; print(#t)

How useful would be these results?"

You may be asking for a # that returns at least a predictable value - or "simply the length". But there are pitfalls also here. Again, in Roberto's words:

"To solve the non-determinism problem, there are at least the
following options:

1 - the number of numeric (integer?) keys
2 - the total number of keys
3 - the largest numeric (integer?) key
4 - the smallest integer key k such that all keys 1..k are present

For a table without holes, all options are equal except 2. Otherwise,
all options are (always?) different.

All options solve the non-determinism of the current #t, but none solves
the real problem of how to give the "length" of a list with holes. (2
may fail even for tables without holes, if the list is mixed with other
non-numeric keys.) Each will be useful in a few particular cases, but
none is generic."

You may now be excited and feel like having found a great opportunity to contribute to improve Lua. And maybe you are the one to come up with the genius solution to this problem. But your solution would have to pass the following conditions:

"a really cheap way to implement 1, 3 or 4 would be welcome, mostly
to improve the documentation. But it should be really cheap, because
it does not solve the real problem anyway. ("really cheap" means
zero memory overhead for tables + zero overhead for table access +
sublinear time for # + very small overhead for table updates + simple
implementation.)"

In the mean time, you might like to browse the mailing list to find the many thoughtful contributions and heartfelt emotions on this hot topic.

Your Lua Community
(you are now a part of it)



Roberto Ierusalimschy schrieb:
Maybe we could collectively have a friendly, instructive standard
answer ready?
    
My standard answer (not sure whether it is instructive) is that there is
no good *meaning* for #t when t has holes. What should be the results
of the following expressions?

  #{[1000] = 1}
  #{1, nil, 3, 4, 5, 6}
  #{1, 2, nil, 4}
  #{[4] = 4, 1, 2}
  #{1, 2, 3, nil, 4, nil, nil}
  #{1, 2, 3; x = 4}
  t = {1, 2, 3, 4}; t[4] = nil; print(#t)
  t = {1, 2, 3};    t[4] = nil; print(#t)

How useful would be these results?


To simply solve the non-determinism problem, there are at least the
following options:

1 - the number of numeric (integer?) keys
2 - the total number of keys
3 - the largest numeric (integer?) key
4 - the smallest integer key k such that all keys 1..k are present

For a table without holes, all options are equal except 2. Otherwise,
all options are (always?) different.

All options solve the non-determinism of the current #t, but none solves
the real problem of how to give the "length" of a list with holes. (2
may fail even for tables without holes, if the list is mixed with other
non-numeric keys.) Each will be useful in a few particular cases, but
none is generic.

So, a really cheap way to implement 1, 3 or 4 would be welcome, mostly
to improve the documentation. But it should be really cheap, because
it does not solve the real problem anyway. ("really cheap" means
zero memory overhead for tables + zero overhead for table access +
sublinear time for # + very small overhead for table updates + simple
implementation.)

-- Roberto