Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between = and == in Pharo Smalltalk?

What is the difference between = and == in Pharo Smalltalk? What are they named, one isEqual and the other?

= ~=    equality / inequality (deep)
== ~~   equality / inequality (shallow)
like image 290
unom Avatar asked Mar 11 '23 03:03

unom


2 Answers

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

  1. Your implementation of = is robust (e.g., banana = car gives no error) and
  2. Every time you redefine = 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 SmallIntegers 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.

like image 98
Leandro Caniglia Avatar answered Apr 01 '23 07:04

Leandro Caniglia


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

like image 39
Uko Avatar answered Apr 01 '23 07:04

Uko