Aye, we would have probably gone with a design similar to what you suggest... if we had generics, but we do not. Generics simply don't fit with the core values of the language. I still believe that there is room for languages without them.
struct cmp
{
hash: *fn(_:*void) u64,
eq : *fn(_:*void, _:*void) bool,
free: *fn(_:*void) void
}
With maybe some default options should be enough for at least the basics.
Note that the indirection overhead would be significant, but without generics or something similar, you don't really have a choice.In the same sense that there's room for languages without, say, for-loops.