Go maps in action
blog.golang.org
blog.golang.org
I know what a hash is. Wow, Go has hashes. Yeah, I knew that too.
blinks So... yeah. I mean, it's the Go blog, so cool. Blog about things in the language, but in terms of 'interesting things about Go' or 'interesting things about tech I expect to see on hacker news frontpage' this is pretty much a 0 for me...
You would be surprised how valuable these kinds of "entry level" articles are. I get more grateful mail about the basic articles than I do the advanced ones, because the audience is so much wider.
So, not for you I guess.
Yeah I've never seen it three minutes ago on frontpage, so the repost is OK for me and people like me.
Maps in Go is definitely a good lesson for hackers who doesn't know about maps...
Quick testing shows that you can use arrays:
func main() {
a := [4]int{1,2,3,4}
m := make(map[[4]int]string)
m[a] = "Hello"
fmt.Println(m[[4]int{1,2,3,4}])
}
Although that will be klunky, since the size of the array is in the type of the array. And still mutable. Mutating keys is bad.In all my years of using maps, I can't think of when I wanted to index by something that was truly an arbitrary-length array of things. If you want to index by something like a tuple of things, declare a datatype for that purpose. What exactly are you trying to do by using a slice as a key?
For an example where you might want to do this consider storing a count of the frequency with which different words follow a given n-gram (sequence of n words) in some corpus, the sort of thing you'd need to make a Markov chain nonsense text generator (like the example programs in chapter 3 of The Practice of Programming: http://cm.bell-labs.com/cm/cs/tpop/code.html).
Of course, you can always take your immutable sequences and represent them as strings, as other languages such as Perl, Awk and Lua force you to do. But I really like that I'm not forced to use such kludges in, say, Python or Haskell.
car54whereareu's code, which uses structs as keys doesn't seem to me as if it would work for variable length sequences given Go's types.
Your solution is what I had in mind when I said above you can concert your keys to strings. The way I see it there are two cases for m[f(a)]:
1. f is injective: this pretty much forces f to return a string, since it must return a data type that is allowed as a key and that can represent arbitrary length sequences without loss of information.
2. f is not injective: then we're using f as a hash function and we need to store the full key inside the value (i.e., m[f(a)]=pair(a,b)) so look ups can make equality checks for the key. You also need to handle f-collisions somehow (I just described disallowing keys with the same f, but that may not work for certain applications). You are basically writing your own hash table at this point.
If you want to tune for performance, you can always replace the convert-to-string code with something custom later. I've seen a few HashTable implementations in Go floating around on the internet.
Because of golang I'm starting to wonder just how many keys a person might want, and that's a different way of thinking for someone used to python or clojure.
The builtin map is limited to types for which the language defines ==. It's a simplifying trade-off; I don't think "acceptable" versus "unacceptable" enters into it. One could imagine expanding the builtin map type to support a hash function, and that was something that was considered early on, but it added complexity that just wasn't needed most of the time.