What is the difference between =
and ==
in Pharo Smalltalk? What are they named, one isEqual
and the other?
= ~= equality / inequality (deep)
== ~~ equality / inequality (shallow)
One important thing to take into account is that =
is not only used explicitly when your code compares two objects. The message =
is also implicitly used by many other messages such as: includes:
, <=
, >=
, remove:
, keyAtValue:
, indexOf:
, upTo:
, peekFor:
, occurrencesOf:
, add:
(in Set
), at:
(and friends at:ifAbsent:
, at:ifAbsentPut:
, etc.), and many others.
This means that when you redefine =
in your class you should make sure that
=
is robust (e.g., banana = car
gives no error) and=
you also redefine hash
.The reason for the first condition is to be able to compare any two objects without the sender having to take any special care before sending the =
message.
The reason for the second is that if in the future your objects are used in a hashed collection (Set
, Dictionary
, Bag
, etc.) they will honor the important invariant required by these entities
IF a = b THEN a hash = b hash
And given that it is a very good practice to make sure that hash
values are SmallIntegers
, one could say
IF a = b THEN a hash == b hash
In other words, every time two objects are considered to be equal their hash
values should be granted to be identical.
Naming
When reading an expression involving =
such as a = b
one says a
is equal to b
or a
equals b
.
When reading a == b
Smalltalkers say a
and b
are the same object, or a
is identical to b
or even a
is equal-equal to b
.
Further comments
The =
message is domain specific, meaning that it is up to you to decide when two Smalltalk objects represent the very same object in your application.
The ==
message is a system feature, meaning that it is implemented by the Virtual Machine (VM) which verifies that the objects being compared occupy the very same location in memory. In other words, two variables a
and b
are equal-equal when they are bound to the very same object.
Examples
a := 'This String'.
b := 'This' , ' ', 'String'.
a == b "false".
a = b "true"
f := 2 / 3.
g := 2 / 3.
f = g "true".
f == g "false"
Generally speaking SmallInteger
s which are =
are also ==
because the VM encodes them in a special way.
n := 3 + 4.
m := 2 + 5.
n = m "true".
n == m "true".
Another interesting case happens with instances of the class Symbol
s := #symbol.
t := 'symbol' asSymbol.
s = t "true".
s == t "true!"
This happens because the Symbol
class makes sure that no two instances with the same underlying string will ever exist in the environment.
Yes, ==
is identity and it uses a primitive to compare if pointers point to the same address (i.e. same object).
=
is equality, meaning that two objects are equal, although they may be 2 different objects. By default =
uses ==
, but it can be reimplemented. Also when you reimplement =
it's advised to also reimplement hash
so hashed collections won't go crazy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With