This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Pharap's profile picture

Lua Table Oddity

Started by Pharap, 18 August 2012 - 11:41 AM
Pharap #1
Posted 18 August 2012 - 01:41 PM
One issue I have encountered lately is regarding tables in lua.

Why is it, that if I do the following:

local tab1 = {3,3,3,3,3,3}
local tab2 = {3,3,3,3,3,3}
if tab1 == tab2 then print("true") else print("false") end
The result is false, and yet if I do this:

local tab1 = {3,3,3,3,3,3}
local tab2 = tab1
if tab1 == tab2 then print("true") else print("false") end
The result is true?

It seems rather illogical that the first should return false, as it means each item has to be tested individually, which is quite impractical.
Even if a table.isEqual(table1, table2) function existed, it would make more sense, but otherwise it's absolute madness.
Ponder #2
Posted 18 August 2012 - 02:08 PM
If I remember correctly the "==" operator does not check whether the given values evaluate equal, but whether they are the same object in memory.

In the first example you create two different tables even though they have the same content. They have to be stored in different locations in memory, because tables are mutable.
In the second example you only create one table, but have it referenced by two variable name. Hence there is only one table stored in memory and since tab1 and tab2 are pointing to the same chunk of memory they are the same.
Cranium #3
Posted 18 August 2012 - 03:27 PM
But this does not make sense… Why would they not be equal, they have the same values??? This is kinda silly if you ask me.
Pharap #4
Posted 18 August 2012 - 04:40 PM
If I remember correctly the "==" operator does not check whether the given values evaluate equal, but whether they are the same object in memory.

In the first example you create two different tables even though they have the same content. They have to be stored in different locations in memory, because tables are mutable.
In the second example you only create one table, but have it referenced by two variable name. Hence there is only one table stored in memory and since tab1 and tab2 are pointing to the same chunk of memory they are the same.
That makes no sense though, because if I ran this:

local var1 = 5
local var2 = 5
if var1 == var2 then print("true") else print("false") end
The result would be true, contradicting the way tables are handled.
In almost any other language, the two tables would be declared equivalent.
If lua was going to implement pointing to memory, surely it would make more sense to handle it like C++ and have an operator for it. It's just plain awkward doing it otherwise.
KaoS #5
Posted 18 August 2012 - 05:28 PM
I know the problem, when you create a new table it is assigned a reference, that is what you get back when you tell it to print the table without specifying a value to read, that reference is unique and so your two tables will not be the same. take a look at this thread and the problem I had… it has a lot to do with this

http://www.computercraft.info/forums2/index.php?/topic/3047-advanced-function-replacement/page__st__20
Ponder #6
Posted 18 August 2012 - 06:12 PM
If I remember correctly the "==" operator does not check whether the given values evaluate equal, but whether they are the same object in memory.

In the first example you create two different tables even though they have the same content. They have to be stored in different locations in memory, because tables are mutable.
In the second example you only create one table, but have it referenced by two variable name. Hence there is only one table stored in memory and since tab1 and tab2 are pointing to the same chunk of memory they are the same.
That makes no sense though, because if I ran this:

local var1 = 5
local var2 = 5
if var1 == var2 then print("true") else print("false") end
The result would be true, contradicting the way tables are handled.
In almost any other language, the two tables would be declared equivalent.
If lua was going to implement pointing to memory, surely it would make more sense to handle it like C++ and have an operator for it. It's just plain awkward doing it otherwise.

Nope, since integers are immutable, there is no need for the interpreter to create two chunks of memory which hold the same value. In your example both var1 and var2 are pointing to the same location and are therefor equal.
That is if I remember correctly, been some time since I read about it.
I do agree with you however that Lua's behavior is irritating there and there should be something like a "is" operator which does that kind of thing.
Lyqyd #7
Posted 18 August 2012 - 08:12 PM
Guys, use the manual.

Equality (==) first compares the type of its operands. If the types are different, then the result is false. Otherwise, the values of the operands are compared. Numbers and strings are compared in the usual way. Objects (tables, userdata, threads, and functions) are compared by reference: two objects are considered equal only if they are the same object. Every time you create a new object (a table, userdata, thread, or function), this new object is different from any previously existing object.

You can change the way that Lua compares tables and userdata by using the "eq" metamethod (see §2.8).
immibis #8
Posted 19 August 2012 - 02:32 AM
Nope, since integers are immutable, there is no need for the interpreter to create two chunks of memory which hold the same value. In your example both var1 and var2 are pointing to the same location and are therefor equal.
That is if I remember correctly, been some time since I read about it.
I do agree with you however that Lua's behavior is irritating there and there should be something like a "is" operator which does that kind of thing.

"is" could be rawequal.
rawequal(a, :D/>/> is the same as the current default behaviour of a == b
Slye #9
Posted 09 September 2012 - 05:26 AM
If I remember correctly the "==" operator does not check whether the given values evaluate equal, but whether they are the same object in memory.

In the first example you create two different tables even though they have the same content. They have to be stored in different locations in memory, because tables are mutable.
In the second example you only create one table, but have it referenced by two variable name. Hence there is only one table stored in memory and since tab1 and tab2 are pointing to the same chunk of memory they are the same.
That makes no sense though, because if I ran this:

local var1 = 5
local var2 = 5
if var1 == var2 then print("true") else print("false") end
The result would be true, contradicting the way tables are handled.
In almost any other language, the two tables would be declared equivalent.
If lua was going to implement pointing to memory, surely it would make more sense to handle it like C++ and have an operator for it. It's just plain awkward doing it otherwise.

I'm not so sure about your assertion that in almost any other language they would be equivalent. In fact, I'd like to know a language that would do this (there probably are some but I can't think of any).

As an example, in Perl, if you do

   my $var1 = [ 3, 3, 3, 3, 3 ];
   my $var2 = [ 3, 3, 3, 3, 3 ]:

..those would most certainly not be equal. The construct there returns a new memory reference into each variable and those are not equal to each other even though they have the same content.

What is frustrating me at the moment is how to actually print the address of a new table in lua…apparently I can check to see if a variable points to the same table but I can't print out the actual identifier for that memory reference. So I cant tell where another timer event is coming from with os.pullEvent() for example.
Lyqyd #10
Posted 09 September 2012 - 05:36 AM
Well, you can. You just have to tostring() the table. It'll create a string in this format: "table: memoryLocationHere".
KaoS #11
Posted 11 September 2012 - 06:44 AM
Is there any way to assign a table to a memory location? so you could essentially assign it a reference. that would make so many things so much easier
kazagistar #12
Posted 11 September 2012 - 07:05 PM
Is there any way to assign a table to a memory location? so you could essentially assign it a reference. that would make so many things so much easier

In what way exactly?
KaoS #13
Posted 12 September 2012 - 07:28 AM
If you make a table and then say print(tablename) it says table: /referencenumber/

that reference number is generated when you make the table and I am wondering if there is a way to set a table to have one of your choosing

EDIT: didn't understand the question, sorry… It would make memory manipulation easier and open multiple loopholes in the system that could be used for instant information transfer over infinite distance etc etc
Edited on 12 September 2012 - 05:30 AM