The best thing about HAMTs is passing immutable ones around, which have free update costs and multi-thread safe. Clojure uses these to represent information that flows through a program. (By free update costs I mean: they are free enough to never rise to the programmer's attention. Obviously ops have costs.)
> Tree based associative arrays (like c++'s std::map) tend to have poor real world performance
That's something HAMT significantly improve upon. You're not going to get linear performances out of them but basic operations are generally O(ln N) where N is usually 32.
- O(1) - standard array (regardless of N)
- O(log_b(N)) - HAMT (b is 32 in clojure)
Since b is big, log_b(N) is quite small even for big numbers, e.g. log_32(2^20) = 4
Also, I'm fairly certain synchronizing isn't an issue because there's nothing to synchronize on since the data structures are immutable. Am I understanding you correctly?
No -- I'm referring to synchronization on the heap itself (think new()/delete()). Multiple threads allocating memory need to synchronize in order to avoid trampling on each other. You can't just get rid of synchronization entirely.