Is there any way to implement hash tables efficiently in a purely functional language? It seems like any change to the hash table would require creating a copy of the original hash table. I must be missing something. Hash tables are pretty darn important data structures, and a programming language would be limited without them.
Is there any way to implement hash tables efficiently in a purely functional language?
Share
Hash tables are a concrete implementation of the abstract “dictionary” or “associative array” data structure. So I think you really want to ask about the efficiency of purely functional dictionaries compared to imperative hash tables.
Yes, hash tables are inherently imperative and there is no direct purely functional equivalent. Perhaps the most similar purely functional dictionary type is the hash trie but they are significantly slower than hash tables due to allocations and indirections.
Dictionaries are a very important data structure (although its worth noting that they were rare in the mainstream until Perl made them popular in the 1990s, so people coded stuff for decades without benefit of dictionaries). I agree that hash tables are also important because they are often by far the most efficient dictionaries.
There are many purely functional dictionaries:
Balanced trees (red-black, AVL, weight-balanced, finger trees etc.), e.g.
Mapin OCaml and F# andData.Mapin Haskell.Hash tries, e.g.
PersistentHashMapin Clojure.But these purely functional dictionaries are all much slower than a decent hash table (e.g. the .NET
Dictionary).Beware Haskell benchmarks comparing hash tables to purely functional dictionaries claiming that purely functional dictionaries are competitively performant. The correct conclusion is that Haskell’s hash tables are so inefficient that they are almost as slow as purely functional dictionaries. If you compare with .NET, for example, you find that a .NET
Dictionarycan be 26× faster than Haskell’s hash table!This is exactly the kind of misinformation I was referring to. Pay no attention to Haskell’s hash tables in this context, just look at the performance of the fastest hash tables (i.e. not Haskell) and the fastest purely functional dictionaries.