JavaScript trick: === can be used to detect two object "a" and "b" if there are pointed to the same object. An object in JavaScript is kind like ref object in nim and every data mutation directly to a can be accessed from b when they are === equal. It's much faster to just compare a === b to know they are identical than comparing every properties.
Suppose in Nim, I have a type:
type A = ref object
x: int
let a = A(x: 1)
let b = a
echo a == b
echo a.unsafeAddr.repr
echo b.unsafeAddr.repr
when it compares with ==, it compares values and returns true. But their pointers are different:
true
ptr 0x10fbabc28 --> ref 0x10fbd1048 --> [x = 1]
ptr 0x10fbabc30 --> ref 0x10fbd1048 --> [x = 1]
Since we learnt the trick of JavaScript, and noticed that both a and b refers to the ref ref 0x10fbd1048. Can I skip value comparing and just figure out that they are the same ref?
You did sorta allude to a solution that works for atleast the C backend. Although I'd argue you would want to use an alternative operator or properly implement this into a smarter way.
type A = ref object
x: int
let a = A(x: 1)
let b = a
proc `==`(a, b: A): bool = a.unsafeAddr == b.unsafeAddr
echo a == b
echo a.unsafeAddr.repr
echo b.unsafeAddr.repr
I was not sure if I could comparing pointers directly, they seen to have diffreret addreses.
a.unsafeAddr == b.unsafeAddr
I need to try again when back to keyboard...
a.unsafeAddr is not what you want here, instead:
cast[pointer](a) == cast[pointer](b)
ref have reference semantics, meaning 2 refs are only equal if their reference/pointer are equal.
2 refs having the same content do not mean they are equal.
In short == does what you want, no need to cast to a pointer. This is one of the main reason to use reference semantics after all. I.e. 2 persons having 2 arms and 2 legs do not mean they are the same person or 2 memory locations having the same size and all zeros do not mean they are the same.
to clarify, (i hope):
== compares values.
let a = 99 #99 is in some slot in memory (a.addr)
let b = 99 #99 is in another slot in memory (b.addr)
a == b # true, the value in slot a is the same as the value in slot b
== compares values even for refs
type A = ref object
x:int
let a,b = A(x: 99) #create two A(x: 99)'s somewhere in memory and put their addresses in a and b.
let c = a #put the value of a (the memory location of the first A(x: 99)) into c
echo c==a #is the value of c equal to the value of a? yes, they both contain the same address
echo c==b #is the value of c equal to the value of b? no, they refer to different A's
echo c[]==b[] #is the value referred to by c the same as the value referred to by b? yes! c.x==b.x
c.x = 97
assert a.x==97 #changing c changed a as well, they are two references to the same object
@shirleyquirk, you are creating the same ref.
See https://play.nim-lang.org/#ix=2z0O
type MyRef = ref object
v: int
let a = MyRef(v: 10)
let b = MyRef(v: 10)
echo a == b # false