Currently tables module require the hash proc to be written manually if the object used as a key.
Why not define default hash function for objects? Something like:
proc hash*[T: tuple|object](o: T): Hash =
var h: Hash = 0
for f in o.fields: h = h !& f.hash
!$h
I like the idea of having a default implementation for objects.
The default implementation should also consider object variants. Related: https://forum.nim-lang.org/t/6781 .
Object identity cannot be automated.
I'm not sure I understand what you mean. As I understand the OP, this is about equality (on a business domain level), not identity. Also, I speak about a default. Of course, it should be possible to override the default implementation with a custom implementation. That said, if the default implementation would be inapplicable in most situations, having the default maybe causes more problems than it solves. Is that what you meant?
In conjunction with tables module having default hash function implementation is a bad idea. For hash-table consistency keys should be immutable, so that their hashes do not change over the lifespan of the key objects.
We already have this situation with the default hash implementations in the hashes module:
import tables
var t = Table[seq[int], int]()
var key = @[1, 2, 3]
t[key] = 3
echo t[key]
key.add(4)
echo t[key]
https://play.nim-lang.org/#ix=2xsB
resulting in
3
/usercode/in.nim(9) in
/playground/nim/lib/pure/collections/tables.nim(262) []
Error: unhandled exception: key not found: @[1, 2, 3, 4] [KeyError]
Client code is responsible for not changing keys.
Agreed.
A possible improvement would be to add autohash helper to hashes module. So we avoid automating object identity and making it easier for people to auto generate hashes for cases when it make sense.
proc autohash*[T: tuple|object](o: T): Hash =
var h: Hash = 0
for f in o.fields: h = h !& f.hash
!$h
proc hash*(v: Something): Hash = v.autohash