The biggest difficulty I'm having reading other people's code is the sheer 
fact that, sometimes, they take the "Short variable name" guideline 
<https://github.com/golang/go/wiki/CodeReviewComments#Variable_Names> to 
heart. It's true that variables should be short enough to convey it's 
meaning, no more and no less, but when it does it become "too much" or "too 
less"? It could be a "I know it when I see it" type of thing, but I don't 
think that's the case, as people have different preferences; maybe one to 
two letter variables are easier to read for some, maybe 3 - 5 for others, 
maybe Hungarian notation (Looking at you Win32), etc. 

The biggest issue is the fact in other languages, you mostly have the type 
name specified next to the declaration, hence you can infer the meaning... 
unfortunately in Go, a lot of people use ':=' over the '=' operator, even 
for extremely ambiguous variable names. If I gave you the code (from 
runtime/hashmap.go)

alg := t.key.alg
hash := alg.hash(key, uintptr(h.hash0))
m := uintptr(1)<<h.B - 1
b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + 
(hash&m)*uintptr(t.bucketsize)))
if c := h.oldbuckets; c != nil {
oldb := (*bmap)(unsafe.Pointer(uintptr(c) + 
(hash&(m>>1))*uintptr(t.bucketsize)))
if !evacuated(oldb) {
b = oldb
}
}

Okay, lessee... alg means algorithm, used to hash the key, thats not so 
bad. What's t? maptype (not to be confused with mapType and MapType 
btw...), which contains the meta-data needed. What's h? Why, the hash-map's 
header; hash0 being the seed (why not call it that?) Phew, well that wasn't 
so bad...

So, what's m? What's that? The modulus? What's B? The logarithmic base-2 
used to find the number of buckets, thank goodness for it's documentation. 
However, why subtract by one? Because then you can turn 1000 0000 => 0111 
1111; How does the letter 'm' represent this? Dunno, maybe it stands for 
modulus? I would have figured 'm' in the context of the hashmap would be 
reserved for, say, the actual map.

Now what is 'm' used for? Note the (hash & m), which will retrieve the 
places where the first B bits are set, hence not all of the hash is 
actually used. Why? Because the first bits set can be used to obtain the 
index. If the hash is 1101 0101, and m is 0111 1111, then (1101 0101) & 
(0111 1111) = 0101 0101. This would give you an index less than the number 
of buckets, 1000 0000. What does this remind you of? A modulus you say? 
Correct, you could have easily done (hash % m) and gotten the same result 
and have it more readable. 

I won't go on too long with this example, but bmap pretty much only has one 
concrete member, the rest are actually allocated outside of the region of 
bmap, and is accessed by using ugly-looking unsafe.Pointer's. 

Then there's the next variable name used, 'c', which has no description 
beyond the fact that it comes after the letter 'b'. Would it have killed 
the developers to add some documentation on what is going on, add some more 
descriptive variable names, etc.? This isn't even the worst of the code 
I've had to sift through.

Hence, clearly this code is not okay, but if the language was written, by 
the developers themselves, who defined the actual guidelines, violate their 
own written guidelines? The real horror to me, is not the fact that I have 
to spend the next 6 weeks reading this stuff and deciphering it, but I find 
myself writing like this now as I got so used to it. 

To clarify I'm not arguing that one-letter variable names are inherently 
bad, as clearly in loops and limited scopes it is fine, such as the index 
in a loop, but I feel as it should be avoided, not encouraged like in the 
code above.

[This is more of a rant than anything though]

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to