“~” is simply the object equality operator. If a and b are two non-void references, then
a = b holds if and only if a and b are references to the same object.
a ~ b holds if and only if the objects to which they refer are of the same type and equal.
The first implies the second. In the second, the definition of when objects are “equal” is given by the `is_equal‘ function, in its version for the common type.
“~” can be seen as an alias to `is_equal' but it is more complicated than that. Per the ECMA spec it is more equivalent to “a.same_type (b) and then a.is_equal (b)”. This ensures that no catcalls occur at runtime.
Previously object equality would have to be written in one of the two forms
a.is_equal (b)
equal (a, b)
but they raise the risk of a run-time “catcall” (non-matching types, here harmless in principle but potentially causing a run-time interrupt anyway). The idiom using ~ is always safe, hence preferred.