That's because 'tag is a macro. When a form is compiled, its first element is checked to see if it's a symbol globally bound to a macro. The compiler has access to the list of local variables at this point (but not their values, since the code isn't running yet), and it could just leave a form alone if its first element is a symbol in that list, but it doesn't.
Should this be changed? Judging by the opinions expressed in http://arclanguage.org/item?id=11685, I'd say yes. But just like I said in that thread, all we need to do to get the behavior we want is to say do.tag!bb so that the 'tag symbol isn't the first element of the form. So for now you can get whichever behavior you want, but the more intuitive behavior takes a bit of "do." boilerplate.
PS: I'm a bit wrong in that thread, actually. It seems (= do.tab.key "something") actually does work just as well as (= .key.tab "something"), and I've been using the former in my code more recently for consistency's sake. I probably made that post based on experiences with an Arc implementation that's been fixed since then.
It seems to me like when a symbol is bound to a name inside a function, that binding should temporarily override whatever is in the global symbol table; but that doesn't seem to be the case.
> It seems to me like when a symbol is bound to a name inside a function, that binding should temporarily override whatever is in the global symbol table; but that doesn't seem to be the case.
Macros are a special case. If it's a globally defined function, then the temporary binding overrides. But if it's a macro, then it doesn't.