core :: Object :: defaultinit
# The root of the class hierarchy.
#
# Each other class implicitly specializes Object,
# therefore the services of Object are inherited by every other class and are usable
# on each value, including primitive types like integers (`Int`), strings (`String`) and arrays (`Array`).
#
# Note that `nullable Object`, not `Object`, is the root of the type hierarchy
# since the special value `null` is not considered as an instance of Object.
interface Object
# Type of this instance, automatically specialized in every class
#
# A common use case of the virtual type `SELF` is to type an attribute and
# store another instance of the same type as `self`. It can also be used as as
# return type to a method producing a copy of `self` or returning an instance
# expected to be the exact same type as self.
#
# This virtual type must be used with caution as it can hinder specialization.
# In fact, it imposes strict restrictions on all sub-classes and their usage.
# For example, using `SELF` as a return type of a method `foo`
# forces all subclasses to ensure that `foo` returns the correct and updated
# type.
# A dangerous usage take the form of a method typed by `SELF` which creates
# and returns a new instance.
# If not correctly specialized, this method would break when invoked on a
# sub-class.
#
# A general rule for safe usage of `SELF` is to ensure that inputs typed
# `SELF` are stored in attributes typed `SELF` and returned by methods typed
# `SELF`, pretty much the same things as you would do with parameter types.
type SELF: Object
# An internal hash code for the object based on its identity.
#
# Unless specific code, you should not use this method but
# use `hash` instead.
#
# As its name hints it, the internal hash code, is used internally
# to provide a hash value.
# It is also used by the `inspect` method to loosely identify objects
# and helps debugging.
#
# ~~~
# var a = "Hello"
# var b = a
# assert a.object_id == b.object_id
# ~~~
#
# The specific details of the internal hash code it let to the specific
# engine. The rules are the following:
#
# * The `object_id` MUST be invariant for the whole life of the object.
# * Two living instances of the same classes SHOULD NOT share the same `object_id`.
# * Two instances of different classes MIGHT share the same `object_id`.
# * The `object_id` of a garbage-collected instance MIGHT be reused by new instances.
# * The `object_id` of an object MIGHT be non constant across different executions.
#
# For instance, the `nitc` compiler uses the address of the object in memory
# as its `object_id`.
#
# TODO rename in something like `internal_hash_code`
fun object_id: Int is intern
# Return true if `self` and `other` have the same dynamic type.
#
# ~~~
# assert 1.is_same_type(2)
# assert "Hello".is_same_type("World")
# assert not "Hello".is_same_type(2)
# ~~~
#
# The method returns false if the dynamic type of `other` is a subtype of the dynamic type of `self`
# (or the other way around).
#
# Unless specific code, you should not use this method because it is inconsistent
# with the fact that a subclass can be used in lieu of a superclass.
fun is_same_type(other: Object): Bool is intern
# Return true if `self` and `other` are the same instance (i.e. same identity).
#
# ~~~
# var a = new Buffer
# var b = a
# var c = new Buffer
# assert a.is_same_instance(b)
# assert not a.is_same_instance(c)
# assert a == c # because both buffers are empty
# ~~~
#
# Obviously, the identity of an object is preserved even if the object is mutated.
#
# ~~~
# var x = [1]
# var y = x
# x.add 2
# assert x.is_same_instance(y)
# ~~~
#
# Unless specific code, you should use `==` instead of `is_same_instance` because
# most of the time is it the semantic (and user-defined) comparison that make sense.
#
# Moreover, relying on `is_same_instance` on objects you do not control
# might have unexpected effects when libraries reuse objects or intern them.
fun is_same_instance(other: nullable Object): Bool is intern
# Have `self` and `other` the same value?
#
# ~~~
# assert 1 + 1 == 2
# assert not 1 == "1"
# assert 1.to_s == "1"
# ~~~
#
# The exact meaning of *same value* is left to the subclasses.
# Implicitly, the default implementation, is `is_same_instance`.
#
# The laws of `==` are the following:
#
# * reflexivity `a.is_same_instance(b) implies a == b`
# * symmetry: `(a == b) == (b == a)`
# * transitivity: `(a == b) and (b == c) implies (a == c)`
#
# `==` might not be constant on some objects overtime because of their evolution.
#
# ~~~
# var a = [1]
# var b = [1]
# var c = [1,2]
# assert a == b and not a == c
# a.add 2
# assert not a == b and a == c
# ~~~
#
# Lastly, `==` is highly linked with `hash` and a specific redefinition of `==` should
# usually be associated with a specific redefinition of `hash`.
#
# ENSURE `result implies self.hash == other.hash`
fun ==(other: nullable Object): Bool do return self.is_same_instance(other)
# Have `self` and `other` different values?
#
# `!=` is equivalent with `not ==`.
fun !=(other: nullable Object): Bool do return not (self == other)
# Display self on stdout (debug only).
#
# This method MUST not be used by programs, it is here for debugging
# only and can be removed without any notice.
#
# TODO: rename to avoid blocking a good identifier like `output`.
fun output
do
'<'.output
object_id.output
'>'.output
end
# Display class name on stdout (debug only).
#
# This method MUST not be used by programs, it is here for debugging
# only and can be removed without any notice.
#
# TODO: rename to avoid blocking a good identifier like `output`.
fun output_class_name is intern
# The hash code of the object.
#
# The hash code is used in many data-structures and algorithms to identify objects that might be equal.
# Therefore, the precise semantic of `hash` is highly linked with the semantic of `==`
# and the only law of `hash` is that `a == b implies a.hash == b.hash`.
#
# ~~~
# assert (1+1).hash == 2.hash
# assert 1.to_s.hash == "1".hash
# ~~~
#
# `hash` (like `==`) might not be constant on some objects over time because of their evolution.
#
# ~~~
# var a = [1]
# var b = [1]
# var c = [1,2]
# assert a.hash == b.hash
# a.add 2
# assert a.hash == c.hash
# # There is a very high probability that `b.hash != c.hash`
# ~~~
#
# A specific redefinition of `==` should usually be associated with a specific redefinition of `hash`.
# Note that, unfortunately, a correct definition of `hash` that is lawful with `==` is sometime tricky
# and a cause of bugs.
#
# Without redefinition, `hash` is based on the `object_id` of the instance.
fun hash: Int do return object_id
end
lib/core/kernel.nit:32,1--225,3