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

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.

Property definitions

core $ Object :: hash
	# 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
lib/core/kernel.nit:196,2--224,34

core $ MapRead :: hash
	# A hashcode based on the hashcode of the keys and the values.
	#
	# ~~~
	# var a = new HashMap[String, Int]
	# var b = new ArrayMap[Object, Numeric]
	# a["one"] = 1
	# b["one"] = 1
	# assert a.hash == b.hash
	# ~~~
	redef fun hash
	do
		var res = length
		for k, v in self do
			if k != null then res += k.hash * 7
			if v != null then res += v.hash * 11
		end
		return res
	end
lib/core/collection/abstract_collection.nit:664,2--681,4

core $ Pointer :: hash
	# Use the address value
	redef fun hash `{ return (long)(intptr_t)self; `}
lib/core/kernel.nit:1080,2--1081,50

core $ Path :: hash
	redef fun hash do return simplified.path.hash
lib/core/file.nit:757,2--46

glesv2 $ GLCap :: hash
	redef fun hash do return val
lib/glesv2/glesv2.nit:717,2--29

cartesian $ Pair :: hash
	redef fun hash do return e.hash * 13 + f.hash * 27
lib/cartesian/cartesian.nit:60,2--51

logic $ CNF :: hash
	redef fun hash do return data.hash
lib/logic/lexpr.nit:378,2--35

core $ SequenceRead :: hash
	# Because of the law between `==` and `hash`, `hash` is redefined to be the sum of the hash of the elements
	redef fun hash
	do
		# The 17 and 2/3 magic numbers were determined empirically.
		# Note: the standard hash functions djb2, sbdm and fnv1 were also
		# tested but were comparable (or worse).
		var res = 17 + length
		for e in self do
			res = res * 3 / 2
			if e != null then res += e.hash
		end
		return res
	end
lib/core/collection/abstract_collection.nit:1021,2--1033,4

core $ Range :: hash
	#     var a = new Range[Int](10, 15)
	#     assert a.hash == 455
	#     var b = new Range[Int].without_last(10, 15)
	#     assert b.hash == 432
	redef fun hash do
		# 11 and 23 are magic numbers empirically determined to be not so bad.
		return first.hash * 11 + last.hash * 23
	end
lib/core/collection/range.nit:127,2--134,4

core $ BM_Pattern :: hash
	redef fun hash do return _motif.hash
lib/core/text/string_search.nit:233,2--37

glesv2 $ GLEnum :: hash
	redef fun hash `{ return self; `}
lib/glesv2/glesv2.nit:506,2--34

matrix $ Matrix :: hash
	redef fun hash do return items.hash_items(width*height)
lib/matrix/matrix.nit:259,2--56

date $ Time :: hash
	redef fun hash do return hour * 1024 + minute * 64 + second
lib/date/date.nit:74,2--60

date $ Date :: hash
	redef fun hash do return year + month * 1024 + day * 2048
lib/date/date.nit:134,2--58

deriving $ DeriveEqual :: hash
	redef fun hash do
		return derive_to_map.hash
	end
lib/deriving/deriving.nit:114,2--116,4

msgpack $ MsgPackExt :: hash
	redef fun hash do return typ.hash + data.hash*8
lib/msgpack/ext.nit:30,2--48

popcorn $ RepoObject :: hash
	redef fun hash do return id.hash
lib/popcorn/pop_repos.nit:425,2--33

core $ Bool :: hash
	redef fun hash do return to_i
lib/core/kernel.nit:504,2--30

core $ UInt32 :: hash
	redef fun hash do return self.to_i
lib/core/fixed_ints.nit:597,2--35

core $ Int8 :: hash
	redef fun hash do return self.to_i
lib/core/fixed_ints.nit:113,2--35

core $ Int16 :: hash
	redef fun hash do return self.to_i
lib/core/fixed_ints.nit:234,2--35

core $ UInt16 :: hash
	redef fun hash do return self.to_i
lib/core/fixed_ints.nit:355,2--35

core $ Int32 :: hash
	redef fun hash do return self.to_i
lib/core/fixed_ints.nit:476,2--35

pthreads $ ConcurrentSequenceRead :: hash
	redef fun hash
	do
		mutex.lock
		var r = real_collection.hash
		mutex.unlock
		return r
	end
lib/pthreads/concurrent_collections.nit:204,2--210,4

ordered_tree $ OrderedTree :: hash
	redef fun hash
	do
		return roots.hash + sub.hash
	end
lib/ordered_tree/ordered_tree.nit:267,2--270,4

poset $ POSet :: hash
	redef fun hash
	do
		var res = 0
		for e, ee in elements do
			if e == null then continue
			res += e.hash
			res += ee.direct_greaters.length
		end
		return res
	end
lib/poset/poset.nit:480,2--489,4

gmp $ Ratio :: hash
    redef fun hash do return self.to_i
lib/gmp/gmp.nit:301,5--38

core $ Char :: hash
	redef fun hash do return code_point
lib/core/kernel.nit:910,2--36

core $ Byte :: hash
	redef fun hash do return self.to_i
lib/core/kernel.nit:613,2--35

core $ Set :: hash
	# Because of the law between `==` and `hash`, `hash` is redefined to be the sum of the hash of the elements
	redef fun hash
	do
		# 23 is a magic number empirically determined to be not so bad.
		var res = 23 + length
		# Note: the order of the elements must not change the hash value.
		# So, unlike usual hash functions, the accumulator is not combined with itself.
		for e in self do
			if e != null then res += e.hash
		end
		return res
	end
lib/core/collection/abstract_collection.nit:493,2--504,4

gmp $ BigInt :: hash
    redef fun hash do return self.to_i
lib/gmp/gmp.nit:133,5--38

core $ Int :: hash
	redef fun hash do return self
lib/core/kernel.nit:714,2--30

core $ Text :: hash
	redef fun hash
	do
		if hash_cache == null then
			# djb2 hash algorithm
			var h = 5381

			for i in [0..length[ do
				var char = chars[i]
				h = (h << 5) + h + char.code_point
			end

			hash_cache = h
		end
		return hash_cache.as(not null)
	end
lib/core/text/abstract_text.nit:1091,2--1105,4

core $ FlatString :: hash
	redef fun hash
	do
		if hash_cache == null then
			# djb2 hash algorithm
			var h = 5381
			var i = _first_byte

			var my_items = _items
			var max = last_byte

			while i <= max do
				h = (h << 5) + h + my_items[i].to_i
				i += 1
			end

			hash_cache = h
		end

		return hash_cache.as(not null)
	end
lib/core/text/flat.nit:637,2--656,4